我有以下类型
type A = {
foo: number
bar: number
}
type B = {
foo: string
bar: string
}
我想写一个函数f()
,它接受一个完全或部分类型为A的参数,并输出一个对象,该对象具有相同的键,但类型为B。
例如,
f(a) = {foo: 1, bar: 2}
// should have return type {foo: string, bar: string}
f(a) = {foo: 1}
// should have return type {foo: string}
f(a) = {bar: 1}
// should have return type {bar: string}
我尝试过使用泛型,但是由于typescript不检查额外的字段,所以当我使用keyof
时,我得到了一个错误:
function f<T extends A>(input: T): {[K in keyof T]: B[K]} {
// Type 'K' cannot be used to index type 'B' ^^^^^
// ... function implementation here
}
如果这个解决方案要起作用,我将不得不以某种方式限制T
仅为A
类型的子集,尽管我还没有找到一种方法来使编译器理解keyof T
可以索引A
。
我最接近的方法是使用Partial
,但这并不是我想要的行为:
function f(input: Partial<A>): Partial<B> {
// mock implementation, output does not matter, asking about types here
const res: Partial<B> = {};
let k: keyof typeof input;
for (k in input) {
const v = input[k];
res[k] = parseInt(v ?? "0");
}
return res;
}
这是不正确的,因为以下输入都给出相同类型的输出:
const a = f({})
const b = f({foo: 1})
const c = f({bar: 2})
// a, b, c all have type {foo?: number, bar?: number)
// should be:
// a: {}
// b: {foo: string}
// c: {bar: string}
我所要求的东西现在在Typescript中是否可行?任何解决方案/变通方法都将不胜感激。
1条答案
按热度按时间jvlzgdj91#
我的建议是将函数
f()
generic设置为input
参数的键K
的类型,然后可以使用Pick<T, K>
实用程序类型将input
表示为Pick<A, K>
,将输出类型表示为Pick<B, K>
:或者,您可以内联
Pick
的定义以获得以下版本:让我们来测试一下:
看起来不错。
Playground代码链接