TypeScript 核心类型与边界
any、unknown 与 never
any
any 会关闭后续类型检查,并且可以赋值给几乎任何类型。它适合迁移旧项目时作为临时逃生口,但不应成为默认方案。
let value: any = 'hello';
value.notExists().anything; // 编译器不会阻止
unknown
unknown 表示“类型暂时未知”。任何值都能赋给它,但使用前必须缩小类型,因此特别适合外部输入。
function parseError(error: unknown): string {
if (error instanceof Error) return error.message;
if (typeof error === 'string') return error;
return 'Unknown error';
}
never
never 表示不可能出现的值,常用于永不返回的函数和穷尽检查。
type Status = 'idle' | 'loading' | 'success';
function assertNever(value: never): never {
throw new Error(`Unexpected value: ${value}`);
}
function render(status: Status) {
switch (status) {
case 'idle': return '等待';
case 'loading': return '加载中';
case 'success': return '完成';
default: return assertNever(status);
}
}
新增联合类型成员后,漏掉分支会在编译期报错。
void、undefined 与 never
undefined 是一个具体值的类型。
void 表示调用方不应使用函数返回值,函数实际仍可能返回内容。
never 表示函数无法正常结束,例如始终抛错或无限循环。
类型断言不是类型转换
const input = document.querySelector('#name') as HTMLInputElement;
as 只影响编译器,不会在运行时检查或转换对象。外部数据仍需使用校验库或手写守卫验证。
type User = { id: number; name: string };
function isUser(value: unknown): value is User {
if (typeof value !== 'object' || value === null) return false;
const user = value as Record<string, unknown>;
return typeof user.id === 'number' && typeof user.name === 'string';
}
object、Object 与 {}
object:非原始类型,通常最符合“对象”的语义。
Object:JavaScript 包装对象接口,原始值也可能满足,不推荐用作普通对象类型。
{}:除 null、undefined 外几乎所有值,不代表空对象。
Record<string, unknown>:更适合描述字符串键对象。
高频回答模板
对可信的内部数据使用明确类型;对接口、存储和用户输入先用 unknown 接收,再通过运行时校验缩小。any 只用于迁移边界,并配置 lint 防止扩散。