TypeScript中的类修饰符和抽象类

8/25/2021 Typescript

在 TypeScript 中,有两种常见的操作符用于处理类型和空值:as!。它们用于类型断言和非空断言,分别用于处理类型和值的问题。本文将介绍它们的用法和区别。

# as 用于类型断言

as 操作符用于告诉编译器你比它更了解某个值的类型,可以将一个值断言为一个特定的类型。这在处理类型不明确或者需要绕过编译器的类型检查时非常有用。

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

在上面的示例中,我们将 someValue 断言为 string 类型,以便获取其 length 属性。这种情况下,编译器会给予相应的类型提示。

但需要注意的是,as 并不会在运行时执行任何操作,它只是告诉编译器如何看待这个值的类型。

# ! 用于非空断言

! 操作符用于告诉编译器,一个值不可能为 nullundefined。这在你确定一个值不会为空的情况下使用。

tsc --strictNullChecks index.ts 运行会有报错提示 error TS2532: Object is possibly 'undefined'

interface Test {
  a?: {
    c: number;
  };
}
const test: Test = {
  a: {
    c: 123
  }
};
console.log(test.a!.c);

在上面的示例中,我们使用 ! 操作符告诉编译器 test.a 不会为 nullundefined,因此可以安全地访问 test.a.c。这可以避免编译器报错,但需要确保你的断言是正确的,否则可能引发运行时错误。

# ? 用于属性描述和属性读取

? 用于属性描述时,表示该属性是可选的,可以省略不写。这在定义类型或接口时非常有用,允许属性的存在是可选的。

type Test = {
  a?: {
    c: number;
  };
};

在属性读取时,? 表示如果属性存在,则返回属性的值,否则返回 undefined

console.log(test.a?.c);

这将会编译成类似下面的代码,只有当 a 存在时才会继续访问 c

console.log(test.a && test.a.c);

# ?? 用于提供默认值

?? 操作符用于提供一个默认值,如果属性不存在或为 nullundefined 时,会返回默认值。

type Test = {
  a: {
    c: number;
  } | undefined;
};

const test: Test = {
  a: {
    c: 123
  }
};

console.log(test.a?.c ?? 1); // 如果 a 值不存在,则输出 1

|| 操作符不同,?? 只在属性值为 nullundefined 时才会返回默认值,不会受到其他 falsy 值的影响。例如0值

type Test = {
  a: {
    c: number;
  } | undefined;
};

const test: Test = {
  a: {
    c: 0
  }
};

console.log(test.a?.c ?? 1); // 0
console.log(test.a?.c || 1); // 1

总结来说,as 用于类型断言,! 用于非空断言,? 用于属性描述和读取时的空值处理,?? 用于提供默认值。根据具体的情况,选择适合的操作符来处理类型和值的问题。