外观
TypeScript 类型系统
- 状态:未准备
- 适用方向:前端 / Go 全栈
- 最近复习:待填写
- 下次复习:待安排
一句话回答
TypeScript 在编译期通过类型关系和控制流缩小错误空间,但类型在运行时通常被擦除;外部接口数据仍需要运行时校验。
原理解释
高频概念
- any 绕开多数类型检查;unknown 允许接收任意值,但使用前必须缩小类型或断言。
- never 表示不可能出现的值,可用于穷尽检查;void 通常表示调用方不使用返回值,与 never 不同。
- 联合类型表示多个可能,交叉类型要求同时满足约束,不兼容属性可能形成 never。
- interface 常用于对象契约,可声明合并;type 可表达联合、元组、映射类型等。两者都能表达很多对象类型。
- 泛型用于保留输入输出之间的关系,不是把 any 换成一个字母。
ts
type Result<T> =
| { ok: true; data: T }
| { ok: false; error: string }
function unwrap<T>(result: Result<T>): T {
if (!result.ok) throw new Error(result.error)
return result.data
}
function pick<T, K extends keyof T>(value: T, key: K): T[K] {
return value[key]
}可辨识联合通过共同的字面量字段缩小类型,适合 WebSocket 消息和请求状态,避免多个无关 boolean 形成非法组合。
场景与边界
as User 不验证 JSON 是 User;非空断言 ! 不会在运行时补上缺失值。readonly 主要提供静态约束,不等于运行时深冻结。开启 strict 后,逐步用 unknown、类型守卫或校验库处理边界数据。
常用工具类型:Partial 使属性可选,Pick 选字段,Omit 排除字段,Record 描述键值映射,ReturnType 提取返回类型;它们通常不递归转换嵌套结构。
项目中的应用
对照 SimulSpeak 字幕与连接消息,检查消息类型和运行时解析是否一致。类型声明存在,不代表服务端每条消息都已被校验。
常见追问
- 结构类型是什么? 通常根据成员形状判断兼容,不必具有同一个类型名称;新鲜对象字面量还受额外属性检查。
- 可选属性和 undefined 一样吗? 属性缺失与存在但值为 undefined 有运行时区别;赋值规则还受 exactOptionalPropertyTypes 配置影响。
- 如何处理新消息类型漏分支? 在 switch default 中将值赋给 never,令未处理的联合分支暴露为编译错误。