如何在打字稿中展平泛型类型声明?
问题描述:
的函数输入一个嵌套通用对象,以及输出平板状物体等如下:
interface Deep<T> {
p1: T;
p2: T;
}
type Nested<T> = {
[P in keyof T]: Deep<any>;
}
type Flat<T, ?> = {
[P in keyof T]: T[P]?;
}
function flat<T extends Nested<T>>(input: T, p: keyof Deep<any>): Flat<T, ?> {
const put: any = {}
for (let k in input)
put[k] = input[k][p]
}
const foo = flat({
name: { p1: 'name', p2: 'name' },
{ fn: { p1:() => 0, p2:() => 1 }
})
在这种情况下,输入是具有不同Deep
类型嵌套对象,希望打字稿可以暗示foo.name
的类型为string
,foo.fn
的类型为() => number
。
我该如何声明Flat<T, ?>
的类型?
答
我不得不修复你的类型和代码,猜测你想做什么,但看起来这是一个你想要的例子inference from mapped types。而不是试图描述一种类型函数Flat<>
,是以输入Nested<?>
和压平其产生的输出类型,执行反向:想到T
作为扁平输出类型和Nested<T>
作为输入的类型:
// this is the same
interface Deep<T> {
p1: T;
p2: T;
}
// changed: for every property of T with key P and value of type T[P],
// there is a property of Nested<T> with key P and value of type Deep<T[P]>
type Nested<T> = {
[P in keyof T]: Deep<T[P]>;
}
// output is T, input is Nested<T> and a key of Deep<>
function flat<T>(input: Nested<T>, p: keyof Deep<any>): T {
const put = {} as T; // assert as type T
for (let k in input)
put[k] = input[k][p];
return put; // added return value
}
我们可以按你想要的方式使用它:
const foo = flat({
name: { p1: 'name', p2: 'name' },
fn: { p1:() => 0, p2:() => 1 },
}, 'p2'); // example code lacked 'p1' or 'p2' argument
foo.name.charAt(0); // works
foo.fn().toFixed(0); // works
希望有帮助;祝你好运!