我具有以下带有2个通用参数的类型:
type Result<INPUT, SPEC> = ...
Result
的具体类型取决于INPUT
和SPEC
的各种组合。
应如何工作:
if(INPUT extends {[key: string]: any}) {
if(SPEC extends {[key: string]: any}) {
Result = {[key in keyof INPUT]: SPEC[key] !== undefined
? Result<INPUT[key], SPEC[key]>
: true
}
} else {
// ...
}
} else {
// ...
}
换句话说:
INPUT
和SPEC
是对象,则Result
应该是键为INPUT
的对象。INPUT
的每个键:检查SPEC
是否包含相同的键true
,则此密钥的值为Result<INPUT[key], SPEC[key]>
false
,则此密钥的值为true
其他信息:
INPUT
和SPEC
是对象,则SPEC
是INPUT
的子集。这意味着:INPUT
可以是{ foo: 42, bar: 42 }
,但是SPEC
只能包含foo
或bar
或两者都包含,或者为空。使用TypeScript可以做到这一点吗?
答案 0 :(得分:2)
根据您的描述,此类型应该可以解决问题:
export type Result<INPUT, SPEC> = INPUT extends object ? SPEC extends object ? {
[K in keyof INPUT]: SPEC extends Record<K, infer SPECK> ?
Result<INPUT[K], SPECK> :
true
} : never : never;
// r is { foo: true; bar: never; goo: { a: never; b: true; }; }
type r = Result<{
foo: number,
bar: string,
goo: { a: number; b: string }
}, { bar: number, goo: { a: number }}>
您可能缺少的部分是SPEC extends Record<K, infer SPECK>
,它测试类型是否使用键K
扩展记录并将该键的类型放入SPECK
。
您不清楚其他分支上会发生什么(如果其中一个类型参数都不是对象,因此我将never
放在此处,但是您可以根据需要进行自定义)
如果我没有100%正确地告诉我,我们可以根据需要进行调整。