基础类型
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)、存量代码改不动。
要点
- 优先推断,必要时注解
- 区分数组与元组
- 外部输入用
unknown,少用any - 有限集合用字面量联合 /
as const,少用enum