类型系统
约 896 字大约 3 分钟
2026-02-09
TypeScript 的类型系统,本质上就是在限定:某个值可能是什么,不可能是什么。有了这套约束后,编辑器和编译器就能在开发阶段提前发现很多问题
类型标注与类型推导
很多时候,TypeScript 会自动推导类型,不一定需要手写标注
const username = 'foo' // 推导为 string
const age = 18 // 推导为 number当变量、函数参数、返回值的意图不够清晰时,再显式标注会更合适
const username: string = 'foo'
function add(a: number, b: number): number {
return a + b
}类型系统
原始类型
最常见的原始类型有:string、number、boolean、bigint、symbol、null、undefined
const title: string = 'TypeScript'
const price: number = 99
const online: boolean = true
const orderId: bigint = 9007199254740993n笔记
String、Number、Boolean 是包装对象类型,日常类型标注优先使用 string、number、boolean
null 与 undefined
在开启 strictNullChecks 后,null 和 undefined 会被严格区分,不再能随意赋值给其他类型
let title: string
// title = undefined // 报错
let optionalTitle: string | undefined
optionalTitle = undefined // OK这也是 TypeScript 能减少 "空值错误" 的关键前提之一
对象类型
除了原始类型,TypeScript 也能描述更复杂的数据结构,比如对象、数组、元组、函数等
对象
对象类型一般使用 interface 或 type 进行描述
interface User {
id: number
name: string
nickname?: string
}const user: User = {
id: 1,
name: 'zjs',
}数组
数组类型一般使用 类型[] 或通过泛型进行描述,这两种写法是等价的,前者更常见
const tags: string[] = ['ts', 'vue']
const scores: Array<number> = [100, 98]元组
元组适合表达 长度固定、每一项类型也固定 的数组,通常使用 [类型, 类型, ...] 的形式进行描述
const point: [number, number] = [120, 30]
const userTuple: [id: number, name: string] = [1, 'zjs']相关信息
如果某个数据结构强依赖位置含义,元组通常比普通数组更准确
其他内置类型
其他内置类型主要有:any、void、never、unknown
any
any 表示任意类型,会跳过类型检查,等价于把这段代码降级回 JavaScript
let data: any = 'hello'
data = 123
data.foo.bar() // 编译不报错,运行期可能直接崩溃unknown
unknown 是更安全的任意类型,使用前必须先缩小类型
let value: unknown = JSON.parse('{"name":"foo"}')
if (typeof value === 'object' && value !== null) {
console.log('safe')
}never
never 表示 永不出现的值
常见场景
- 函数永远不会正常返回,比如直接抛错
- 联合类型已经被分支穷尽,剩下的值理论上不应该再出现
function fail(msg: string): never {
throw new Error(msg)
}
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; size: number }
function area(shape: Shape) {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius * shape.radius
case 'square':
return shape.size * shape.size
default: {
// 走到这里说明前面的分支没有覆盖完整
// 但按 Shape 的定义,shape 在这里本该已经没有可能的值,因此类型是 never
const exhaustive: never = shape
return exhaustive
}
}
}void
void 常用于函数返回类型,表示不关心返回值
function log(msg: string): void {
console.log(msg)
}只读与可选
可选属性
可选属性使用 ? 表示,表示属性可以不存在,如果存在,则必须是该类型
interface Profile {
id: string
avatar?: string
}只读属性
只读属性使用 readonly 表示,表示属性不能被修改
interface Profile {
readonly id: string
name: string
}const profile: Profile = {
id: 'u_1',
name: 'A',
}
profile.id = 'u_2' // 报错:只读属性不能被重新赋值只读也能用于数组:
const list: readonly number[] = [1, 2, 3]
list.push(4) // 报错