TypeScript 里的 class field
例子如下:
![](http://n4.ikafan.com/assetsj/blank.gif)
和这个知识点相关的 tsc 编译选项:strictPropertyInitialization
![](http://n4.ikafan.com/assetsj/blank.gif)
strictPropertyInitialization 设置控制是否需要在构造函数中初始化类字段。
![](http://n4.ikafan.com/assetsj/blank.gif)
正确做法:
class GoodGreeter { name: string; constructor() { this.name = "hello"; } }
![](http://n4.ikafan.com/assetsj/blank.gif)
请注意,该字段需要在构造函数本身中进行初始化。 TypeScript 不会分析您从构造函数调用的方法来检测初始化,因为派生类可能会覆盖这些方法并且无法初始化成员。
class 成员需要在构造函数里进行初始化操作。如果在构造函数里调用其他函数,然后在这些其他函数里进行字段初始化,这样也不行。
如果一定要这样做,即您打算通过构造函数以外的方式明确初始化字段(例如,可能外部库正在为您填充类的一部分),您可以使用明确赋值断言运算符,!:
class OKGreeter { // Not initialized, but no error name!: string; }
如果一个 class field 设置为 readonly,这表示它只能在构造函数内被赋值。
![](http://n4.ikafan.com/assetsj/blank.gif)
子类构造函数的第一行语句,必须是 super() 函数调用;
![](http://n4.ikafan.com/assetsj/blank.gif)
什么是 TypeScript class 里的成员方法
准确定义:A function property on a class is called a method.
除了标准类型注解之外,TypeScript 不会向方法添加任何其他新内容。
需要注意的是,在 TypeScript 方法实现内部,必须用 this. 来访问其成员变量。
![](http://n4.ikafan.com/assetsj/blank.gif)
下列代码里,m 方法内部,访问的是 class 外部定义的类型为 number 的 x 变量,而不是 class 内部类型为 string 的变量。
let x: number = 0; class C { x: string = "hello"; m() { // This is trying to modify 'x' from line 1, not the class property x = "world"; Type 'string' is not assignable to type 'number'.Type 'string' is not assignable to type 'number'. } }
class 的访问其 accessors
class C { _length = 0; get length() { return this._length; } set length(value) { this._length = value; } }
TypeScript 对访问器有一些特殊的推理规则:
(1)如果get存在但没有set,则该属性自动为只读 (2)如果没有指定setter参数的类型,则根据getter的返回类型推断 (3)Getter 和 setter 必须具有相同的成员可见性
关于 TypeScript class 继承和接口实现的一些坑
重要的是要理解implements 子句只是检查类是否可以被视为接口类型。 它根本不会改变类的类型或其方法。 一个常见的错误来源是假设一个implements 子句会改变类的类型——它不会!
看这个例子:
interface Checkable { check(name: string): boolean; } class NameChecker implements Checkable { check(s) { // Notice no error here return s.toLowerCase() === "ok"; } } const a = new NameChecker(); console.log(a.check('ok'));
语法错误:
![](http://n4.ikafan.com/assetsj/blank.gif)
原因是因为第 6 行代码里,我们没有为 check 方法的参数 s 指明类型,因此其类型默认为 any. 这就和 interface Checkable 里定义的 check 方法的输入参数类型 string 不一致了。
解决办法:
![](http://n4.ikafan.com/assetsj/blank.gif)
同样,使用可选属性实现接口不会创建该属性:
interface A { x: number; y?: number; } class C implements A { x = 0; } const c = new C(); c.y = 10;
![](http://n4.ikafan.com/assetsj/blank.gif)
解决办法:
![](http://n4.ikafan.com/assetsj/blank.gif)