我目前正在编写一个函数的打字,该函数接受一个Clazz<U>
对象数组,并返回一个U
数组。U
在所有参数之间并不总是相同的。
是否可以将返回类型设置为U
的所有值的数组
我尝试了很多方法,包括keyof
和typeof
的各种用法,但简单地在打字中这样做似乎没有任何结果。通过调用(instanceof Clazz).value
来访问每个Clazz
项的U
类型的值。
示例函数:(GitHub上下文中的实际代码(
function example(input: Array<Clazz<U>>): Array<U> {
const out = [];
for(const item of input) {
out.push(item.value); // where item.value instanceof U === true
}
return out;
}
理想结果:
// if this is possible it would be fantastic!
example([new Clazz('this is a string'), new Clazz(500)]); // output type: [string, number]
// a union is acceptable!
example([new Clazz('this is a string'), new Clazz(500)]); // output type: Array<string | number>
我将把这个实现用于T
。。。我不会称它为CCD_ 11,因为这个名称通常用于泛型类型参数。我改为Tee
:
class Tee<U> {
constructor(public value: U) { }
}
以下是我如何编写example()
:
function example<X extends Array<Tee<any>>>(input: X | []) {
const out = [] as any as { [K in keyof X]: X[K] extends Tee<infer U> ? U : never };
for (const item of input) {
out.push(item.value);
}
return out;
}
那里发生了一些事情。一种是example
是一个泛型函数,其泛型类型参数X
被约束为某种类似Tee
的东西(Tee<any>
(的数组。假设input
参数的类型为X
(我将在下面解释X | []
(。那么输出类型就是我们断言的out
:
{ [K in keyof X]: X[K] extends Tee<infer U> ? U : never }
也就是说,将数组类型X
映射到另一个数组类型,其中我们使用条件类型推断为每个元素打开Tee<U>
到U
的包装。这就是你要找的类型操纵。
编译器不可能仅仅通过检查example()
的实现就知道你正在进行类型操作,这就是为什么我必须使用类型断言来告诉它out
将是什么
最后一个要解释的位是input
类型中的| []
。这只是一个提示,编译器将尝试将为input
传递的数组文字解释为元组类型,而不是无序数组,正如在microsoft/TypeScript#227179的这篇评论中所解释的那样,这是一个GitHub问题,要求找到一种更喜欢元组而不是无序阵列的方法。如果没有| []
,您可能会得到一个无序的数组(我想您对此很满意,但不是必须的(。
足够的解释,让我们测试一下:
example([new Tee('this is a string'), new Tee(500)]); // [string, number]
看起来不错!好吧,希望能有所帮助;祝你好运
游乐场链接到代码