繁体   English   中英

Typescript 数组中通用参数的并集

[英]Typescript union of generic parameters in array

我有一个带有三个通用参数的接口,看起来像这样

interface X<A,O,I> {
...
}

我想创建一个 function 接受这些接口的数组作为 rest 参数,这样 O 和 I 的类型相同,但 A 的类型可以不同。 此外,我希望返回类型是 A 的所有类型的联合。

let item1: X<Type1,string,string> = value1;
let item2: X<Type2,string,string> = value2;

// I want the return type for this to be 'Type1 | Type2'
myFunction(item1, item2) 

我一直在考虑这个问题,想不出什么好办法。 想知道是否还有其他人对如何实现这一目标有更好的想法。

编辑:根据 wantok 的回答,我最终得到了这个

type ExtractFirst<T> = T extends X<infer A, unknown, unknown>[] ? A : never;

export function myFunction<T extends Array<X<any, unknown, I>>, I>(input: I, ...types: T): ExtractFirst<T> {
  ...
}

我不知道我是否理解正确,或者我很笨,但从我的角度来看它真的很简单:D

const myFunction (item1: Item1Interface, item2: Item2Interface): Type1 | Type2 => {}

或者,如果您想“动态地”从 function 参数中读取类型,我希望您可以这样做:

const myFunction (item1: Item1Interface, item2: Item2Interface): typeof item1 => {}
interface X<A, O, I> {
    getA(): A;
}
// The other generic types of X don't have to be unknown, but they
// need to be something.

function myFunction<T>(...items: Array<X<T, unknown, unknown>>): T {
    return items[0].getA();
}
const item1: X<string, string, string> = { ... };
const item2: X<number, string, string> = { ... };

const v = myFunction(item1, item2); // This doesn't compile.
// Argument of type 'X<number, string, string>' is not assignable to
// parameter of type 'X<string, unknown, unknown>'.
//  Type 'number' is not assignable to type 'string'.

const v = myFunction<string | number>(item1, item2); // This does compile.

如果不同项目上的A类型不相同,则需要告诉 function 您传递的是哪种类型。 实际上,这应该没什么大不了的,因为您要么手动构建项目,因此,您应该知道需要传递的联合,或者您从其他地方获得项目列表,在这种情况下,您必须已经有一个它们都符合的类型。

如果您有一个项目数组,您还可以使用条件类型来提取联合类型。

type ExtractFirst<T> = T extends X<infer A, unknown, unknown>[] ? A : never;
const args = [item1, item2];

// equivalent to myFunction<string | number>(..args);
const v = myFunction<ExtractFirst<typeof args>>(...args);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM