类属性中的非空断言

Dar*_*ren 7 typescript sequelize-typescript

我对打字稿相当陌生,并在网上搜索试图找到对此的解释。

最近我一直在做一个项目,并想使用sequelize 来完成它。在阅读文档的打字稿部分时,我遇到了下面的示例:

// These are all the attributes in the User model
interface UserAttributes {
  id: number;
  name: string;
  preferredName: string | null;
}

// Some attributes are optional in `User.build` and `User.create` calls
interface UserCreationAttributes extends Optional<UserAttributes, "id"> {}

class User extends Model<UserAttributes, UserCreationAttributes>
  implements UserAttributes {
  public id!: number; // Note that the `null assertion` `!` is required in strict mode.
  public name!: string;
  public preferredName!: string | null; // for nullable fields

  // timestamps!
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;

  //other code
}
Run Code Online (Sandbox Code Playgroud)

在类内部,preferredName也具有非空断言运算符,但随后继续在其类型中包含 null。

这是否会覆盖静态类型检查,因为它在运行时可能为空(即用户没有首选名称)?

或者对于为什么他们会在该属性上包含非空运算符有更好的解释吗?例如排除 undefined 但包含 null。

jca*_*alz 8

这主要是一个术语问题:

  • nullundefined是不同的,尽管语言的某些部分对它们的处理方式相似。(例如,非空断言运算符从它所操作的表达式的域中消除null和。)undefined

  • !类属性声明之后是明确赋值断言运算符,而不是非空断言运算符。(它们都是用后缀编写的!,但是非空断言出现在表达式之后而明确赋值断言出现在变量/属性声明之后。)明确赋值断言告诉编译器它不需要验证变量或属性在使用前已初始化。明确赋值断言运算符与 无关null

如果您不初始化属性或变量,则如果您从中读取,其值将是undefined,而不是。null如果您启用了编译--strictPropertyInitialization器选项(或仅启用了,其中包括它),并且您有一个类型不包括(not )--strict的类属性,那么您必须在声明时立即初始化它,在构造函数内无条件地初始化它,或者使用明确的赋值断言:undefinednull

class Example {
    a: string | undefined; // okay: includes undefined
    b: string | null = "b"; // okay: initialized
    c: string | null; // okay: assigned in constructor
    d: string | null; // error: compiler cannot be sure it is assigned
    e!: string | null; // okay: asserted as assigned

    constructor() {
        this.c = "c";
        if (Math.random() < 1000) {
            this.d = "d"
            this.e = "e";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Playground 代码链接