特殊类型
any:任意类型(关闭类型检查)unknown:未知类型(比any更安全,需要类型缩小)never:永远不会有值(函数抛异常或死循环的返回类型)void:没有返回值(常用于函数返回类型)
any
- 含义:表示任意类型,赋值时类型检查。
- 特点:编译器完全放弃检查,你可以对
any类型的值做任何事。 - 危险性:容易引入 bug。
ts
let value: any;
value = 123;
value = 'hello';
value = { foo: 'bar' };
// 可以随便用,不会报错
value();
value.toUpperCase();
value.nonExist.prop.deep;unknown
- 含义:任意类型,但是会开启类型检查
- 特点:你不能直接对
unknown做任何操作,必须先 类型缩小(type narrowing)。 - 优势:强制开发者进行类型检查。
| 特性 | any | unknown |
|---|---|---|
| 类型检查 | 关闭检查 | 需要缩小后才能用 |
| 可赋值性 | 可赋值给任意类型 | 只能赋值给 any 或 unknown |
| 安全性 | 不安全,容易出 bug | 更安全,强制类型守卫 |
| 使用场景 | 临时跳过检查、快速原型开发 | 处理外部数据(如接口返回值) |
ts
let value: unknown;
value = 123;
value = 'hello';
value = { foo: 'bar' };
// ❌ 报错:不能直接操作 unknown
// value.toUpperCase();
// ✅ 必须先缩小类型
if (typeof value === 'string') {
console.log(value.toUpperCase()); // ok
}never
never:空范围,产生于不合理的类型运算
可以赋值给任何类型,但没有任何类型能赋值给它(除了 never 本身)。
ts
type A=number & stringA会被编译器推断为never类型,因为不存在一个值既可以是number类型又是string类型
ts
let a: never;
// a = 123; // ❌ 报错
// a = "hello"; // ❌ 报错
// a = undefined; // ❌ 报错应用场景:
- 抛出异常的函数
ts
function error(message: string): never {
throw new Error(message);
}检查不可达分支
如果触发default,说明存在业务逻辑错误,需要我们完善代码
ts
type Shape = "circle" | "square";
function getArea(shape: Shape) {
switch(shape) {
case "circle": return Math.PI;
case "square": return 1;
default:
const _exhaustiveCheck: never = shape; // ❌ 如果有新成员报错
return _exhaustiveCheck;
}
}模板字面量类型
模板字面量类型是 TS 4.1 引入的类型。它允许你把字面量类型像 JS 模板字符串一样拼接、裁剪、变换,最终得到一个新的字符串字面量类型集合。
- 语法与 JS 模板字符串一模一样
ts
type World = "world";
type Greeting = `hello ${World}`; // "hello world"- 拼接的“变量”只能是字面量类型或其联合
ts
type Method = "GET" | "POST";
type Endpoint = `/${Method}/user`; // "/GET/user" | "/POST/user"- 支持
string,number,boolean,bigint占位符
ts
type Verbose = `id-${string}`; // 任意以 "id-" 开头的字符串
type N = `item-${number}`; // "item-0", "item-1", …- 配合
infer做“字符串模式匹配”——类型层面的正则
ts
type ExtractId<T> = T extends `id-${infer Id}` ? Id : never;
type T1 = ExtractId<"id-123">; // "123"
type T2 = ExtractId<"user-456">; // never- 与
keyof交叉,精准筛选对象键
ts
type Props = {
onClick: () => void;
onHover: (e: Event) => void;
name: string;
};
type EventHandlers = keyof Props & `on${string}`;
// "onClick" | "onHover"