TypeScript中如何用一个接口的键索引另一个接口的类型
解决TypeScript中函数返回类型匹配传入参数键的问题
首先看你遇到的类型错误:Type 'Property' cannot be used to index type 'ValueType',原因是你定义的Obj1KeysWithObj2Values泛型中,KeyType extends Obj1意味着keyof KeyType是Obj1键的子集,但ValueType extends Obj2允许ValueType是Obj2的子类型,导致Property可能不在ValueType的键集合里。而你实际场景中ValueType固定是Obj2,不需要作为泛型参数传入,直接绑定即可。
修正自定义类型
可以把自定义类型改成这样,去掉多余的ValueType泛型:
type Obj1KeysWithObj2Values<T extends Obj1> = { [K in keyof T]: Obj2[K] }
或者更简洁地用TypeScript内置的Pick工具类型,效果完全一致:
// 等价于上面的自定义类型 type Obj1KeysWithObj2Values<T extends Obj1> = Pick<Obj2, keyof T>
调整函数实现
原来的函数用Partial<Obj2>作为返回对象的初始类型,再断言为目标类型,导致TypeScript无法精确约束返回的键。可以直接将返回对象初始化为目标类型,再根据传入的参数赋值:
interface Obj1 { a?: string b?: string c?: number } interface Obj2 { a: boolean b: string c: number } type Obj1KeysWithObj2Values<T extends Obj1> = Pick<Obj2, keyof T> const myFunc = <T extends Obj1>(obj: T) => { const returnObj = {} as Obj1KeysWithObj2Values<T>; if (obj.a !== undefined) { returnObj.a = true; } if (obj.b !== undefined) { returnObj.b = '1'; } if (obj.c !== undefined) { returnObj.c = 20; } return returnObj; } // 测试调用:resultObj的类型为 {a: boolean; b: string} const resultObj = myFunc({ a: 'hello', b: 'hello' })
这样修改后,resultObj的类型会严格匹配你传入的键,并且每个键的类型对应Obj2中的定义,不会包含未传入的键。
内容的提问来源于stack exchange,提问作者U Rogel
相关产品推荐
相关产品推荐

