如何将TypeScript的class/interface属性作为数据类型使用
语法层面的基础解决方案
你需要使用TypeScript提供的索引访问类型实现需求,仅需将点号取值的写法改为方括号包裹属性名即可:
interface foo { bar: string; } // 正确写法,foo['bar']等价于string类型 function baz(bar: foo['bar']) { // 业务代码 }
适配业务防混淆场景的进阶方案
上面的写法只能提取属性的基础类型,如果你需要彻底区分不同接口下类型相同的同名字段(比如两个接口的ID都是string,但不允许互相传参),可以配合**标记类型(Branded Type)**实现,不需要为每个属性单独定义独立类型:
// 通用标记工具类型,无需修改 type Brand<T, Tag extends string> = T & { __tag: Tag } // 定义接口时给需要区分的字段加唯一标记 interface User { id: Brand<string, 'user_id'> name: string } interface Order { id: Brand<string, 'order_id'> amount: number } // 限制仅接受用户ID作为参数 function getUserInfo(userId: User['id']) {} const userId = '123' as User['id'] const orderId = '123' as Order['id'] getUserInfo(userId) // 类型校验通过 getUserInfo(orderId) // 类型报错,避免混淆
如果原有接口已经定义完成无法直接修改,也可以通过类型运算批量添加标记:
// 原有已经定义好的原始接口 interface RawUser { id: string name: string } // 仅给id字段加标记,其他属性保持原有类型 type User = Omit<RawUser, 'id'> & { id: Brand<RawUser['id'], 'user_id'> }
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

