Skip to main content

TypeScript Interface 用法速查

· 3 min read

Interface 是 TS 定义对象/数组结构的主力工具——核心是 形状契约,不是类继承。

  • 对象类型interface Person { name; age } 限定对象必须有哪些字段
  • 可选字段name?: string 表示可有可无
  • 只读字段readonly age 防止外部修改
  • 索引签名[key: string]: any 描述动态字段
  • Duck typing:TS 是结构化类型,多余字段传入不报错

对象类型:核心用法

interface Person {
name: string
age: number
}

const p1: Person = { name: 'Kimi', age: 20 } // OK
const p2: Person = { name: 'Kimi', a: 20 } // Error: 'a' 不存在
const p3: Person = { name: 'Kimi', age: '100' } // Error: age 类型错

接口是形状契约——变量必须按形状填齐字段,多一个少一个都不行。


可选字段 ?

interface Person {
name: string
age: number
gender?: string // 可选
}

const p1: Person = { name: 'Kimi', age: 20 } // OK
const p2: Person = { name: 'Kimi', age: 20, gender: 'm' } // OK

访问可选字段返回 T | undefined,必须先 narrow:

if (p1.gender !== undefined) {
p1.gender.toUpperCase() // OK
}
tip

配合 strictNullChecks(2026 默认开启),可选字段会强制你处理 undefined 情况。


只读字段 readonly

interface Person {
name: string
readonly age: number
}

const p: Person = { name: 'Kimi', age: 20 }
p.age = 18 // Error: Cannot assign to 'age' because it is a read-only property

readonly编译期保护,运行时只是普通属性——可以通过类型断言绕过,但不要这么干。


索引签名:动态字段

interface Person {
name: string
age: number
[key: string]: any // 允许任意额外字段
}

const p: Person = { name: 'Kimi', age: 20, gender: 'm', id: 888 }

两种签名:

  • [key: string]: T —— 字符串 key(默认)
  • [index: number]: T —— 数字 key(数组用法)
warning

所有声明字段的类型必须兼容索引签名的类型。如果索引签名是 number,那所有字段都必须是 number 或 number 的子类型。

interface Bad {
name: string // Error: string 不能赋值给 number 索引类型
[index: number]: number
}

interface vs type:怎么选

维度interfacetype
合并自动合并(同名字段)不合并,重复声明报错
联合/交叉只能用 & 合并原生支持联合
扩展extends 多继承& 交叉类型
适配场景对象形状 API、库类型联合类型、复杂类型运算
tip

简单对象形状用 interface,需要 union / 复杂运算用 type。两者 80% 场景能互换。


数组用法

用索引签名定义数组类型:

interface StringArray {
[index: number]: string
}

const arr: StringArray = ['a', 'b']
arr[0] = 123 // Error

数组也支持 readonly

interface ReadonlyStringArray {
readonly [index: number]: string
}

const arr: ReadonlyStringArray = ['a', 'b']
arr[1] = 'c' // Error
warning

现代 TS 优先用 readonly string[] 而不是 interface 索引签名——更简洁,IDE 提示更好。


Duck typing:多余字段不报错

interface Person {
name: string
age: number
}

function handle(p: Person) {
console.log(p.name, p.age)
}

// 通过变量传入:多余字段不报错
const user = { name: 'Kimi', age: 20, gender: 'm' }
handle(user) // OK

// 直接传对象字面量:多余字段报错
handle({ name: 'Kimi', age: 20, gender: 'm' }) // Error

这是 TS 的结构化类型(structural typing):只要对象形状兼容,多余字段无所谓。但对象字面量是"新鲜出炉"的,TS 会做额外属性检查。


References

  1. TypeScript Handbook: Interfaces —— 官方手册
  2. TypeScript Handbook: Object Types —— 对象类型详解