TypeScript 中的问号?和感叹号!

745 阅读1分钟

问号操作符

在 TypeScript 中有四个地方会出现 ? 操作符:

1. 三元运算符

const isCN = country === 'China' ? true : false;

2. 函数可选参数

function getUsername(firstName: string, lastName?: string){}

3. 可选成员(类、接口)

class A {
  name?: string
}

interface B {
  name?: string
}

4. 链判断运算符(ES2020 optional chaining operator)

const firstName = message?.body?.user?.firstName || 'default';

感叹号操作符

在 TypeScript 中有三个地方会出现 ! 操作符:

1. 一元运算符

const isShow = !isModalHide();

2. 成员

// 因为接口B里面name被定义为可空的值,但是实际情况是不为空的,
// 那么我们就可以通过在class里面使用!,重新强调了name这个不为空值
class A implemented B {
  name!: string
}

interface B {
  name?: string
}

TypeScript 2.7 引入了一个新的控制类型检查的标记 --strictPropertyInitialization,这个参数规定每个实例属性都会在构造函数里或使用属性初始化器赋值。

class Person {
  name: string;
  country: string;
  constructor() {
    this.name = 'Louis';
  }
}

在 strictPropertyInitialization 打开的情况下,上面的代码编译器会报错:error TS2564: Property 'country' has no initializer and is not definitely assigned in the constructor.

如果我们不想在初始化的时候为country赋值,此时就可以用!修饰该属性:

class Person {
  name: string;
  country!: string;
  constructor() {
    this.name = 'Louis';
  }
}

3. 非空断言操作符(Non-null Assertion Operator)

TypeScript also has a special syntax for removing null and undefined from a type without doing any explicit checking. Writing ! after any expression is effectively a type assertion that the value isn’t null or undefined:

function liveDangerously(x?: number | null) {
  // No error
  console.log(x!.toFixed());
}

Just like other type assertions, this doesn’t change the runtime behavior of your code, so it’s important to only use ! when you know that the value can’t be null or undefined.


参考: