TypeScript:对象字面量(大括号对象、type、interface) 作者:马育民 • 2026-08-02 08:46 • 阅读:10006 # 介绍 TS 中 `{}` 代表 **对象类型字面量**,区别于 JS 普通对象,用来 **约束对象的结构**: - 属性名 - 属性类型 - 可选属性 - 只读属性 - 方法 - 索引签名等 ### 区分 JS、TS大括号对象 - `const obj = {}` → JS 对象实例 - `type T = {}` → TS对象类型约束 ### 应用场景 - 定义简单实体结构(最常用)。比如:AJAX接口返回数据、表单、简单模型,一次性定义数据结构 - 函数参数 / 返回值约束 - 配置对象、选项参数 # 定义方式1-type定义 使用 `type` 定义对象结构 - `type`:TS 用来 **[创建自定义类型别名](https://www.malaoshi.top/show_1GW3eWpclvRg.html "创建自定义类型别名")** 的语法。 - `User`:自定义类型名称(首字母大写,约定俗成)。 - `=` 后面大括号 `{ ... }` →【对象字面量类型】 ### 定义对象结构 ``` // 定义类型别名 User type User = { id: number; name: string; age?: number; // 可选属性 }; ``` ##### 解释: `id: number;` 必填属性:对象必须有 id,值必须是数字,不能省略。 ##### 解释:`name: string;` 必填属性:必须有 name,值为字符串,不能省略。 ##### 解释 age?: number; - 对象可以写 age,也可以不写 age; - 如果写上 age,值必须是 number; - 不写 age 等价于 age: number | undefined。 ### 定义对象,有age ``` const u1: User = { id: 1, name: "小明", age: 18 } ``` ### 定义对象,没有age(允许,因为age是可选) ``` const u2: User = { id: 2, name: "小红" } ``` ### 错误定义对象 ```ts // 缺少必填 name,报错 const u3: User = { id: 3 } // id 传字符串,类型不匹配,报错 const u4: User = { id: "4", name: "小李" } ``` # 定义方式2-interface 描述一个对象必须具备什么结构。 ### 定义接口 ``` interface User { id: number; name: string; age?: number; // 可选属性 } ``` ##### 解释: `id: number;` 必填属性:对象必须有 id,值必须是数字,不能省略。 ##### 解释:`name: string;` 必填属性:必须有 name,值为字符串,不能省略。 ##### 解释 age?: number; - 对象可以写 age,也可以不写 age; - 如果写上 age,值必须是 number; - 不写 age 等价于 age: number | undefined。 ### 定义对象,有age ``` const u1: User = { id: 1, name: "小明", age: 18 } ``` ### 定义对象,没有age(允许,因为age是可选) ``` const u2: User = { id: 2, name: "小红" } ``` ### 错误定义对象 ```ts // 缺少必填 name,报错 const u3: User = { id: 3 } // id 传字符串,类型不匹配,报错 const u4: User = { id: "4", name: "小李" } ``` # 两种定义方式的选择 定义大括号对象,一般情况,`type` 与 `interface` 区别不大 ### 优先选择 type(90% 前端业务,接口返回数据、表单) - 定义后端返回 DTO、列表数据、普通对象 - 需要用到联合类型 |、多种状态分支 - 类型不需要外部扩展、一次性结构 - 需要组合多个类型(交叉 &) ### 优先选择 interface - 需要声明合并(扩充全局类型、框架类型拓展) - 编写类 class implements 实现规范 - 设计通用对外暴露的公共 API、组件约束 # 常见用法 ### 1. 可选属性 `?` 属性可以不提供,值允许 `undefined` ```typescript type User = { id: number; email?: string; // 可选 } const u1: User = { id: 1 }; const u2: User = { id: 2, email: "a@qq.com" }; ``` ### 2. 只读属性 `readonly` 属性**初始化后不能修改**,仅约束类型层面 ```typescript type User = { readonly id: number; name: string; } const u: User = { id: 1, name: "test" }; u.id = 2; // ❌ 报错,只读无法修改 u.name = "new"; // ✅ ``` > 注意:`readonly` 只限制属性重新赋值,**不限制对象内部可变数据** ```typescript type Data = { readonly list: number[] } const d: Data = { list: [1,2] }; d.list.push(3); // ✅ 正常,数组引用没变 ``` ### 3. 对象内定义方法 两种写法等价 ```typescript type Person = { // 写法1:函数属性 sayHi: () => void; // 写法2:方法简写(推荐) greet(name: string): string; } const p: Person = { sayHi() { console.log("hi"); }, greet(name) { return `Hello ${name}`; } } ``` ### 4. 空对象类型 `{}` ```typescript type EmptyObj = {}; ``` ⚠️ 重大误区: `{}` **不是“空对象,不能有任何属性”** `{}` 代表:**可以拥有任意属性,但是不能使用 `null` / `undefined`** ```typescript let o: {}; o = 1; // ✅ o = "abc"; // ✅ o = {}; // ✅ o = null; // ❌ ``` 如果你想要**完全空对象,禁止任何属性**: ```typescript type StrictEmpty = Record const e: StrictEmpty = {}; e.xxx = 1; // ❌ 报错 ``` ### 5. 属性修饰组合 ```typescript type T = { readonly uid: number; desc?: string | null; } ``` # 常见坑 & 易错点 ### 坑1:字面量对象多余属性直接赋值报错 ```typescript type User = { id: number } const u: User = { id: 1, name: "xx" } // ❌ 对象字面量直接赋值会校验多余属性 ``` 绕过方案(不推荐,尽量规范): ```typescript const temp = { id:1, name:"xx" } const u: User = temp; // ✅ 变量中转不再严格校验额外属性 ``` ### 坑2:readonly 仅类型层面,编译后消失 TS 编译成 JS 没有只读限制,运行时依然可以修改。如需运行时保护要用 `Object.freeze` ### 坑3:区分 `{}`、`object`、`Record` 1. `{}`:允许除 null/undefined 以外所有值(原始值、对象都行) 2. `object`:**只允许引用类型**(数组、对象,不能是 number/string 原始值) 3. `Record`:键为字符串的普通对象 ```typescript let a: {}; let b: object; a = 1; // ✅ b = 1; // ❌ ``` 原文出处:http://www.malaoshi.top/show_1GW3msf4Dxxg.html