字符串

  1. let firstname: string = 'Captain'; // 字符串字面量
  2. let familyname: string = String('S'); // 显式类型转换
  3. let fullname: string = `my name is ${firstname}.${familyname}`; // 模板字符串

说明:所有 JavaScript 支持的定义字符串的方法,我们都可以直接在 TypeScript 中使用。

数字

  1. /** 十进制整数 */
  2. let integer: number = 6;
  3. /** 十进制整数 */
  4. let integer2: number = Number(42);
  5. /** 十进制浮点数 */
  6. let decimal: number = 3.14;
  7. /** 二进制整数 */
  8. let binary: number = 0b1010;
  9. /** 八进制整数 */
  10. let octal: number = 0o744;
  11. /** 十六进制整数 */
  12. let hex: number = 0xf00d;
  13. /** 大整数 */
  14. let big: bigint = 100n;

请注意:虽然number和bigint都表示数字,但是这两个类型不兼容。

布尔

  1. /** TypeScript 真香 为 真 */
  2. let TypeScriptIsGreat: boolean = true;
  3. /** TypeScript 太糟糕了 为 否 */
  4. let TypeScriptIsBad: boolean = false;

Symbol

  1. let sym1: symbol = Symbol();
  2. let sym2: symbol = Symbol('42');

数组

  1. /** 子元素是数字类型的数组 */
  2. let arrayOfNumber: number[] = [1, 2, 3];
  3. /** 子元素是字符串类型的数组 */
  4. let arrayOfString: string[] = ['x', 'y', 'z'];
  5. /** 子元素是数字类型的数组 */
  6. let arrayOfNumber: Array<number> = [1, 2, 3];
  7. /** 子元素是字符串类型的数组 */
  8. let arrayOfString: Array<string> = ['x', 'y', 'z'];

元组

  1. const x: [State, SetState] = [state, setState];
  2. const y: [SetState, State] = [setState, state];

使得定义包含固定个数元素、每个元素类型未必相同的数组成为可能。元组相较对象而言,不仅为我们实现解构赋值提供了极大便利,还减少了不少代码量,这可能也是 React 官方如此设计核心 Hooks 的重要原因之一。

特殊类型 any

any 指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式。

any 类型会在对象的调用链中进行传导,即所有 any 类型的任意属性的类型都是 any,如下代码所示:

  1. let anything: any = {};
  2. let z = anything.x.y.z; // z 类型是 any,不会提示错误
  3. z(); // 不会提示错误

TS 中的 any 指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式。

长远的角度来看,应该避免使用 any。如果在 TS 项目中,导出都是 any,那和直接书写 js 没什么区别,TS 也失去了意义。因此除非有特殊情况,不然应禁止使用 any 类型。

unknown

TS 3.0 新添加的一个类型,用于注解不不确定的变量类型。例如:

  1. let result: unknown;
  2. if (x) {
  3. result = x();
  4. } else if (y) {
  5. result = y();
  6. } ...

但是与 any 类型不同的是,unknown 类型更加安全,比如我们可以将任意类型的值赋值给 unknown,但是 unknown 只能赋值给 any 和 unknown 类型。使用 unknown 后,TS 会对它做类型校验,但是如果不缩小类型。对 unknown 执行的操作将会报错。

void 、undefined、null

可以把 undefined 值或类型是 undefined 的变量赋值给 void 类型变量,反过来,类型是 void 但值是 undefined 的变量不能赋值给 undefined 类型。

never

never 表示永远不会发生值的类型。

  • 定义一个统一抛出错误的函数 ```javascript function ThrowError(msg: string): never {

    throw Error(msg);

}

  1. - 函数代码中是一个死循
  2. ```javascript
  3. function InfiniteLoop(): never {
  4. while (true) {}
  5. }

never 是所有类型的子类型,它可以给所有类型赋值,但是除了 never 自身以为,其他类型都不能为 never 赋值。

比如我们可以把 never 作为接口类型下的属性类型,用来禁止写接口下特定的属性,示例代码如下:

  1. const props: {
  2. id: number,
  3. name?: never
  4. } = {
  5. id: 1
  6. }
  7. props.name = null; // ts(2322))
  8. props.name = 'str'; // ts(2322)
  9. props.name = 1; // ts(2322)

静态类型检测


在编译(转译)时期,TypeScript 编译器将通过对比检测变量接收值的类型与我们显示注解的类型,从而检测类型是否存在错误。如果两个类型完全一致,显示检测通过;如果两个类型不一致,它就会抛出一个编译期错误,告知我们编码错误。

TypeScript 的语言服务可以和 VS Code 完美集成。因此,在编写代码的同时,我们可以同步进行静态类型检测(无须等到编译后再做检测),极大地提升了开发体验和效率。

类型断言(Type Assertion)

类型断言,告诉 TS 按照我们的方式进行类型检查。

注意:类型断言的操作对象必须满足某些约束关系,否则我们将得到一个 ts(2352) 错误,即从类型“源类型”到类型“目标类型”的转换是错误的,因为这两种类型不能充分重叠。

此外还有一种特殊非空断言,即在值(变量、属性)的后边添加 ‘!’ 断言操作符,它可以用来排除值为 null、undefined 的情况,具体示例如下:

  1. let mayNullOrUndefinedOrString: null | undefined | string;
  2. mayNullOrUndefinedOrString!.toString(); // ok
  3. mayNullOrUndefinedOrString.toString(); // ts(2531)