我有两个具有相同可选键但值不同的接口:
interface Obj1 {
a?: string
b?: string
c?: number
}
interface Obj2 {
a: boolean
b: string
c: number
}
Obj1是一个函数参数,另一个Obj2是这个函数的返回值,我希望返回值只标识Obj1上的给定键,所以如果Obj1只包含a
和b
,那么Obj2也只包含a
和b
。
我尝试使用下面的方法,但得到ts错误Type 'Property' cannot be used to index type 'ValueType'
type Obj1KeysWithObj2Values<KeyType extends Obj1, ValueType extends Obj2> = {
[Property in keyof KeyType]: ValueType[Property]
}
**UPDATE:**函数及其调用
const myFunc = <T extends Obj1>({ a, b, c }: T) => {
const returnObj: Partial<Obj2> = {}
if (a) {
returnObj.a = true
}
if (b) {
returnObj.b = '1'
}
if (c) {
returnObj.c = 20
}
return returnObj as Obj1KeysWithObj2Values<T, Obj2>
}
const resultObj = myFunc({ a: 'hello', b: 'hello' })
如果你尝试一下,你会发现在resultObj
上你得到了你传递给函数的任何东西,只要它在接口Obj1中,不管Obj2是什么。
4条答案
按热度按时间nqwrtyyt1#
考虑使用Pick〈Type,Keys〉,它是标准库的一部分:
第一个参数表示源对象,第二个参数表示应选取的键的并集
在您的情况下,还需要使Obj1关键帧和Obj2关键帧相交:
Playground
8fsztsew2#
问题是,尽管您知道
Obj2
总是有一个Obj1
的键的超集,但TypeScript并不知道,因此需要确认。:-)如果您想使用这些泛型,可以通过使用条件类型测试属性键是否也存在于ValueType
中来清除该错误:Playground示例
q1qsirdb3#
这个answer完全是
generic
,它工作。我只是想分享一些类似的东西,我用
Intl
把Date
转换成一个自定义的DateTimeFormatParts
的日期,除了它是部分通用的。事情是这样的:
将此应用于您的案例,您可以基于原始类型创建自定义类型:
现在你可以创建一个函数来返回obj1中定义的属性:
t5zmwmid4#
这不是我的代码,虽然它仍然是一个有价值的答案。它是由另一个用户张贴,不久后的答案被删除,所以我不知道谁给予信贷。
我对此的解释是,尽管可以随意改进,
Obj1KeysWithObj2Values
是接受两个参数的泛型类型:KeyType
,它扩展了函数param类型。ValueType
,它扩展了函数返回类型。然后声明一个新类型,该类型是一个对象,其键作为
KeyType
中的键,值类型(如果可以在ValueType
上找到)将从那里继承类型或将为never
。