TypeScript 里的 class field

举报
汪子熙 发表于 2022/06/19 17:49:36 2022/06/19
【摘要】 例子如下:和这个知识点相关的 tsc 编译选项:strictPropertyInitializationstrictPropertyInitialization 设置控制是否需要在构造函数中初始化类字段。正确做法:class GoodGreeter { name: string; constructor() { this.name = "hello"; }}请注意,该字段需要在构...

例子如下:

和这个知识点相关的 tsc 编译选项:strictPropertyInitialization

strictPropertyInitialization 设置控制是否需要在构造函数中初始化类字段。

正确做法:

class GoodGreeter {
  name: string;

  constructor() {
    this.name = "hello";
  }
}

请注意,该字段需要在构造函数本身中进行初始化。 TypeScript 不会分析您从构造函数调用的方法来检测初始化,因为派生类可能会覆盖这些方法并且无法初始化成员。

class 成员需要在构造函数里进行初始化操作。如果在构造函数里调用其他函数,然后在这些其他函数里进行字段初始化,这样也不行。

如果一定要这样做,即您打算通过构造函数以外的方式明确初始化字段(例如,可能外部库正在为您填充类的一部分),您可以使用明确赋值断言运算符,!:

class OKGreeter {
  // Not initialized, but no error
  name!: string;
}

如果一个 class field 设置为 readonly,这表示它只能在构造函数内被赋值。

子类构造函数的第一行语句,必须是 super() 函数调用;

什么是 TypeScript class 里的成员方法

准确定义:A function property on a class is called a method.

除了标准类型注解之外,TypeScript 不会向方法添加任何其他新内容。

需要注意的是,在 TypeScript 方法实现内部,必须用 this. 来访问其成员变量。

下列代码里,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'));

语法错误:

原因是因为第 6 行代码里,我们没有为 check 方法的参数 s 指明类型,因此其类型默认为 any. 这就和 interface Checkable 里定义的 check 方法的输入参数类型 string 不一致了。

解决办法:

同样,使用可选属性实现接口不会创建该属性:

interface A {
  x: number;
  y?: number;
}
class C implements A {
  x = 0;
}
const c = new C();
c.y = 10;

解决办法:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。