TypeScript中object类型是什么?未知键对象参数选object还是索引签名
TypeScript object类型定义、适用场景及方案选型
1. object类型定义
TypeScript 中的object是类型系统内置的基础类型,代表所有非原始类型的值,也就是排除了string/number/boolean/null/undefined/symbol/bigint这些原始类型的所有值,普通对象、数组、函数、类实例都属于object类型的范围。
2. object类型适用场景
仅推荐以下两种场景使用object类型:
- 你不需要访问参数的任何自定义属性,只需要限制输入为非原始值。比如写通用工具函数判断对象是否为空、计算对象字节大小等,只需要调用Object原型方法或者遍历键,不需要读取具体属性值。
- 作为泛型约束的基础限制,比如
function handleObj<T extends object>(arg: T) {},用来限制泛型参数必须是对象类型,后续可以结合泛型推导属性类型。
3. 两种方案选型对比
首先给出两个方案的代码:
方案A
const edit: (value: object) => void = value=> {// do something } edit({name: "Bob", age: 11})
方案B
type JSONObject = { [k: string]: string | number} const edit: (value: JSONObject ) => void = value=> {// do something }
方案A的问题
使用object作为参数类型时,TS不会允许你访问value上的任何自定义属性,哪怕你确定传了name属性,写value.name也会直接报错,因为object类型没有声明任何可访问的属性,完全是黑盒状态,除了Object原型自带的方法,你没法用它做任何业务逻辑处理。
方案B的优势
这里用索引签名明确声明了对象的键是字符串类型,值是string | number的联合类型,完全满足「参数可能包含任意未知对象键」的需求:
- 你可以自由访问
value上的任意字符串键,TS不会报错,还能自动推导值的类型为string | number - 传参时只要满足键是字符串、值是数字/字符串的要求,不管传多少个未知属性都能通过类型校验
最终结论
该场景下必须选择B方案,除非你在edit函数中完全不需要访问value的任何自定义属性,才可以考虑用A方案。
如果需要支持更复杂的值类型,可以调整索引签名的联合类型,比如允许布尔值、嵌套对象就写成{[k: string]: string | number | boolean | JSONObject},或者需要完全不限制值类型可以直接用Record<string, any>,使用体验都远优于object类型。
内容的提问来源于stack exchange,提问作者vuvu
相关产品推荐
相关产品推荐

