从输入项的类型参数推断输出数组类型



我目前正在编写一个函数的打字,该函数接受一个Clazz<U>对象数组,并返回一个U数组。U在所有参数之间并不总是相同的。

是否可以将返回类型设置为U的所有值的数组

我尝试了很多方法,包括keyoftypeof的各种用法,但简单地在打字中这样做似乎没有任何结果。通过调用(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]

看起来不错!好吧,希望能有所帮助;祝你好运

游乐场链接到代码

最新更新