如何从对象映射中根据id获取对应name的类型?
问题解决:根据id获取对应name的TypeScript类型
你的问题出在(ValueOf<Obj> & { id: T })['name']的写法上——因为ValueOf<Obj>是一个联合类型,和{id: T}交叉后,TypeScript不会自动过滤掉不匹配id的成员,而是会保留所有成员的name属性,最终形成联合类型。
要实现根据id精准获取对应name的类型,你可以通过提取联合类型中匹配id的成员来实现,具体有两种常用方式:
方式一:使用Extract工具类型
直接用Extract从ValueOf<Obj>中筛选出id等于T的成员,再取它的name属性:
const obj = { foo: { id: 1, name: 'one' }, bar: { id: 2, name: 'two', }, baz: { id: 3, name: 'three' }, } as const type Obj = typeof obj; type ValueOf<T> = T[keyof T]; type Ids = ValueOf<Obj>['id']; // 修改后的GetName类型 type GetName<T extends Ids> = Extract<ValueOf<Obj>, { id: T }>['name'] type Foo = GetName<1> // 类型为"one" type Bar = GetName<2> // 类型为"two" type Baz = GetName<3> // 类型为"three"
方式二:构造id到name的映射类型
先提前创建一个以id为键、name为值的映射类型,后续直接通过键取值:
const obj = { foo: { id: 1, name: 'one' }, bar: { id: 2, name: 'two', }, baz: { id: 3, name: 'three' }, } as const type Obj = typeof obj; type ValueOf<T> = T[keyof T]; // 构造id到name的映射类型 type IdToNameMap = { [V in ValueOf<Obj> as V['id']]: V['name'] } type GetName<T extends keyof IdToNameMap> = IdToNameMap[T] type Foo = GetName<1> // "one" type Bar = GetName<2> // "two"
第一种方式更直接,适合你的场景;第二种方式提前构造了完整的id-name映射,适合需要多次使用该关联关系的场景。
内容的提问来源于stack exchange,提问作者macabeus
相关产品推荐
相关产品推荐

