interface用于描述对象结构,声明属性名、类型、可选性(?)和只读性(readonly),仅在开发阶段校验,不运行时约束。

用 interface 声明对象类型,核心是描述对象“长什么样”——包括有哪些属性、类型是什么、是否必须存在、能否修改。它不是运行时的约束,而是在开发阶段帮你看清结构、提前发现错误。
基础声明与确定属性
接口默认要求所有属性都必须存在且类型匹配:
- 用
interface关键字开头,名称通常首字母大写(如User) - 属性后跟冒号和类型,用分号或换行分隔
- 赋值时不能多也不能少,类型也必须严格一致
interface User {
name: string;
age: number;
}
const u1: User = { name: 'Alice', age: 30 }; // ✅ 正确
// const u2: User = { name: 'Bob' }; // ❌ 缺少 age
// const u3: User = { name: 'Charlie', age: 30, id: 1 }; // ❌ 多了 id
添加可选属性(用 ?)
有些属性在实际数据中可能不存在,比如用户资料里的 phone 或 avatar,这时加 ? 表示可有可无:
- 语法:属性名后紧跟
?,如phone?: string - 赋值时可以省略该字段,TS 不报错
- 访问前建议用可选链
?.或判断是否存在,避免运行时报错
interface UserProfile {
name: string;
age: number;
phone?: string; // 可选
}
const p1: UserProfile = { name: 'David', age: 25 }; // ✅ 没有 phone 也合法
const p2: UserProfile = { name: 'Eve', age: 28, phone: '123' }; // ✅ 有 phone 也合法
console.log(p1.phone?.length); // 安全访问
设置只读属性(用 readonly)
readonly 是编译期保护,表示该属性只能在对象创建时赋值,之后不可重新赋值:
- 语法:属性前加
readonly,如readonly id: number - 只读属性在初始化时必须提供值(除非是可选只读属性,但极少用)
- 注意:
readonly不递归冻结嵌套对象,内部属性仍可修改
interface Product {
readonly id: number;
name: string;
tags: string[];
}
const prod: Product = { id: 1001, name: 'Laptop', tags: ['tech'] }; // ✅ 初始化赋值
// prod.id = 1002; // ❌ 编译报错:无法分配到 "id" ,因为它是只读属性
prod.tags.push('sale'); // ✅ 合法:tags 本身不是只读数组
组合使用与注意事项
可选和只读可以共存,但需注意语义合理性:
-
readonly name?: string表示“如果存在,就不能改”,但很少见,通常只读属性都应是确定存在的 - 若需整个对象不可变,要用
Readonly<t></t>工具类型,或把数组声明为readonly string[] - 一旦用了索引签名(如
[key: string]: any),所有明确属性的类型必须能被其兼容











