类型系统概述
在 TypeScript 的类型系统中,any
、unknown
和 never
是三个特殊的类型,它们各自具有独特的特性和使用场景。从集合论的角度来看:
any
和unknown
是顶层类型(top type),可以包含所有其他类型never
是底层类型(bottom type),不包含任何值
any 类型
基本特性
any
类型表示没有任何限制,该类型的变量可以赋予任意类型的值。从集合论的角度看,any
类型是所有其他类型的全集。
|
|
类型检查关闭
当变量类型设为 any
时,TypeScript 会关闭该变量的类型检查:
|
|
类型污染
any
类型存在污染问题,可以赋值给其他任何类型:
|
|
使用场景
特殊情况下关闭类型检查
1 2
// 处理第三方库的类型问题 const thirdPartyLib: any = require('some-library');
JavaScript 项目迁移
1 2
// 迁移旧项目时临时使用 const legacyData: any = getLegacyData();
动态数据处理
1 2
// 处理动态 API 响应 const response: any = await fetchData();
unknown 类型
基本特性
unknown
是 TypeScript 3.0 引入的类型,可以视为严格版的 any
。它表示类型不确定,可能是任意类型,但使用上有严格限制。
|
|
使用限制
不能赋值给其他类型
1 2 3 4 5
let v: unknown = 123; let v1: boolean = v; // 报错 let v2: number = v; // 报错 let v3: string = v; // 报错
不能直接访问属性和方法
1 2 3 4 5 6 7 8
let v1: unknown = { foo: 123 }; v1.foo; // 报错 let v2: unknown = 'hello'; v2.trim(); // 报错 let v3: unknown = (n = 0) => n + 1; v3(); // 报错
允许的操作
unknown
类型变量只能进行以下操作:
|
|
类型收窄
使用类型收窄后,可以安全地使用 unknown
类型:
|
|
never 类型
基本特性
never
类型表示永远不会发生的类型,不包含任何值。从集合论的角度看,它是空集。
|
|
使用场景
永不返回的函数
1 2 3
function throwError(): never { throw new Error('Error'); }
穷尽性检查
1 2 3 4 5 6 7 8 9 10 11 12 13
type Shape = 'circle' | 'square'; function getArea(shape: Shape): number { switch (shape) { case 'circle': return Math.PI * radius * radius; case 'square': return side * side; default: const _exhaustiveCheck: never = shape; return _exhaustiveCheck; } }
类型收窄
1 2 3 4 5 6 7 8 9
function processValue(value: string | number) { if (typeof value === 'string') { // value 被收窄为 string 类型 } else if (typeof value === 'number') { // value 被收窄为 number 类型 } else { // value 被收窄为 never 类型 } }
最佳实践
避免使用 any
- 优先使用具体的类型
- 如果必须使用,添加
// @ts-ignore
注释说明原因
使用 unknown 替代 any
- 处理外部数据时使用
unknown
- 通过类型收窄安全地使用
- 处理外部数据时使用
合理使用 never
- 用于表示不可能的情况
- 帮助 TypeScript 进行穷尽性检查
总结
类型 | 描述 | 特点 | 使用场景 |
---|---|---|---|
any | 任意类型 | 关闭类型检查,可污染其他类型 | 旧项目迁移,第三方库集成 |
unknown | 未知类型 | 类型安全,需要类型收窄 | 处理外部数据,API 响应 |
never | 空类型 | 不包含任何值 | 穷尽性检查,永不返回的函数 |
记住:
any
和unknown
是顶层类型,可以承接任何类型never
是底层类型,可以赋值给任何类型- 优先使用
unknown
而不是any
- 使用
never
进行穷尽性检查