主题
06 · TypeScript 进阶(实用向)
目标:收窄
any;会写泛型约束与联合收窄;组件 props / API 类型能讲清。
官方:Handbook
1. 背景与目标
类型是工程边界,不是体操比赛。实用优先:让 tsc 拦住低级错,面试能讲「为什么这样标」。
2. 核心概念
| 手段 | 用途 |
|---|---|
unknown + 收窄 | 代替 any 接外部数据 |
| 联合 + 可辨识字段 | kind: 'ok' | 'err' 分支 |
泛型约束 T extends ... | 函数复用仍保类型 |
| 工具类型 | Pick / Omit / Partial / Required |
少用 as | 断言是逃生舱,不是默认路径 |
3. 最小实践
3.1 收窄 unknown
ts
function parseUser(input: unknown): { id: string; name: string } {
if (
typeof input === 'object' &&
input !== null &&
'id' in input &&
'name' in input &&
typeof (input as { id: unknown }).id === 'string' &&
typeof (input as { name: unknown }).name === 'string'
) {
return { id: input.id, name: input.name }
}
throw new Error('invalid user')
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
生产可换成 zod 等运行时校验——类型不能代替校验。
3.2 API 与 Store 示意
ts
type Note = { id: string; title: string; content: string }
type ApiOk<T> = { code: 0; data: T }
type ApiErr = { code: number; message: string }
type ApiResult<T> = ApiOk<T> | ApiErr
function isOk<T>(r: ApiResult<T>): r is ApiOk<T> {
return r.code === 0
}
// Pinia / 模块状态
type NoteState = {
list: Note[]
currentId: string | null
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3.3 组件 props(Vue 示意)
ts
const props = defineProps<{
noteId: string
readonly?: boolean
}>()1
2
3
4
2
3
4
React 同理用 type Props = { ... }。
4. 踩坑与取舍
- 到处
any:一时爽,重构哭。 - 乱
as:骗过编译器,运行仍炸。 - 只信类型、不做运行时校验:后端一变全军覆没。
- 过度体操:条件类型套十层,同事读不懂——抽成命名类型即可。
5. 验收清单
- [ ] 一个模块里
any显著减少,关键路径用unknown或明确类型 - [ ] 给 store 或 API 补齐类型,并通过
tsc/ IDE 检查 - [ ] 能口述:联合收窄、泛型约束各一例
- [ ] 知道何时该加运行时校验
