TypeScript 概览
自动关联目录:TypeScript 概览
心智模型:类型是一个集合
把类型理解成"值的集合",很多规则就自然了:
| 写法 | 集合含义 |
|---|---|
string | 所有字符串的集合 |
'a' | 'b' | 只含两个元素的集合 |
A & B | 交集(同时满足) |
A | B | 并集(满足其一) |
unknown | 全集 |
never | 空集 |
赋值是否合法 = 源集合是否是目标集合的子集。这就是为什么 string 不能赋给 'a',反之可以。
基础类型
| 类型 | 说明 |
|---|---|
string number boolean | 原始类型 |
bigint symbol | 需要对应 target 支持 |
null undefined | 严格模式下独立 |
void | 函数无返回值 |
never | 永不返回(抛错、死循环) |
unknown | 未知,使用前必须收窄 |
any | 关闭检查 |
object / {} | 注意 {} 也接受基本类型,别用来表示"任意对象" |
unknown 与 any 的区别是最常被问到的:两者都能接受任何值,但 unknown 不允许直接使用,必须先收窄。所以新代码里凡是想写 any,先考虑 unknown。
收窄(Narrowing)
类型守卫让编译器把联合类型收敛到具体分支:
function len(x: string | string[]) {
if (typeof x === "string") return x.length; // 此处 x: string
return x.length; // 此处 x: string[]
}| 守卫 | 适用 |
|---|---|
typeof | 原始类型 |
instanceof | 类实例 |
in | 判断属性/方法存在 |
| 字面量比较 | 判别联合(discriminated union) |
自定义谓词 x is T | 复杂判断 |
Array.isArray | 数组 |
判别联合是最值得掌握的模式:
type Result =
| { kind: "ok"; data: string }
| { kind: "err"; msg: string };
function handle(r: Result) {
switch (r.kind) {
case "ok": return r.data; // r 已收窄
case "err": return r.msg;
}
}接口与类型别名
interface | type | |
|---|---|---|
| 对象形状 | 可以 | 可以 |
| 联合/交叉/元组/条件类型 | 不行 | 可以 |
| 声明合并 | 支持(可多次声明累加) | 不支持 |
| 扩展 | extends | & |
实践建议:描述对象形状用 interface,其他一切用 type。这个约定让代码风格统一,也避开了 interface 不能表达联合的限制。
泛型
function first<T>(xs: T[]): T | undefined { return xs[0]; }泛型是"类型层面的函数":输入类型,输出类型。
| 机制 | 用途 |
|---|---|
<T> | 类型参数 |
extends | 约束(T extends { id: string }) |
keyof T | 取键的联合 |
T[K] | 索引访问类型 |
默认参数 <T = string> | 减少重复书写 |
实用内置类型
| 类型 | 效果 |
|---|---|
Partial<T> | 全部可选 |
Required<T> | 全部必填 |
Pick<T, K> / Omit<T, K> | 挑/去若干键 |
Record<K, V> | 键值映射 |
Readonly<T> | 只读 |
ReturnType<F> / Parameters<F> | 从函数类型反推 |
Awaited<T> | 展开 Promise |
NonNullable<T> | 去 null/undefined |
与 JavaScript 的关系
- TS 只做编译期类型检查,运行时类型信息被擦除
enum与namespace是少数会生成运行时代码的 TS 特性private只是编译期约束,运行时仍是普通属性(要真私有用#field)interface编译后完全消失,不能用作运行时判断
常见错误
| 错误 | 原因 |
|---|---|
Object is possibly 'undefined' | 索引/可选属性没收窄 |
Type 'X' is not assignable to 'Y' | 集合不是子集,通常字段少了 |
This expression is not callable | 联合类型里各方签名不一致 |
过度使用 as | 用守卫收窄更安全 |
strict 关着时"能编译但运行时崩" | 类型没真正生效 |
许可协议:CC BY
作者:Davids
本文链接:https://hustjjd.github.io/5605a405.html
更新于:2026年10月10日