跳到主要内容

基础类型

TypeScript 在 JS 值上叠加静态类型。先掌握高频内置类型与几个「特殊」类型。

原始类型与注解​

let count: number = 1;
let title: string = "ts";
let ok: boolean = true;

多数情况可依赖类型推断,不必处处手写:

let count = 1; // number

数组与元组​

const nums: number[] = [1, 2, 3];
const also: Array<string> = ["a", "b"];

// 元组:固定长度与位置类型
const pair: [string, number] = ["age", 18];

any / unknown / never​

类型含义使用建议
any关闭检查,可赋给任意类型尽量避免;迁移遗留代码时的逃生舱
unknown未知,使用前必须收窄接收外部输入时的默认选择
never永不产生值(穷尽分支、总抛错)用于完整性检查
function parse(input: unknown) {
if (typeof input === "string") {
return input.toUpperCase();
}
throw new Error("expected string");
}

function fail(msg: string): never {
throw new Error(msg);
}

字面量类型与联合​

type Direction = "left" | "right" | "up" | "down";
let move: Direction = "left";
// move = "forward"; // Error

const yes = true as const; // 字面量 true,不是 boolean

const 断言把值收成最窄字面量,常用于配置对象。既要类型又要运行时值时,用 as const 对象,不必上 enum:

const Status = {
Pending: "pending",
Success: "success",
Failed: "failed",
} as const;

type Status = (typeof Status)[keyof typeof Status];
// "pending" | "success" | "failed"

enum:少用​

enum 是 TS 自带语法,看起来像「一组命名常量」,但会编译成真正的 JS 对象(类型会被擦除,enum 不会)。

enum Status {
Pending, // 0
Success, // 1
}

function handle(s: Status) {}
handle(Status.Pending);
handle(999); // 也能过:数字 enum 几乎等于 number

数字 enum 还有反向映射(Status[0] === "Pending"),遍历、序列化时容易多出意外的 key。const enum 会内联、不生成对象,但和 isolatedModules / Babel / esbuild 不友好,跨包引用也容易对不上。

新代码优先字面量联合或上面的 as const 对象。仍可接受的场景:对接数字枚举的后端、位标志(1 | 2 | 4)、存量代码改不动。

要点​

  1. 优先推断,必要时注解
  2. 区分数组与元组
  3. 外部输入用 unknown,少用 any
  4. 有限集合用字面量联合 / as const,少用 enum