数组中通用参数的打字稿联合

时间:2021-06-17 18:42:53

标签: typescript

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

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

我想创建一个函数,该函数接受这些接口的数组作为其余参数,以便 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> {
  ...
}

2 个答案:

答案 0 :(得分:0)

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

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

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

const myFunction (item1: Item1Interface, item2: Item2Interface): typeof item1 => {}

答案 1 :(得分:0)

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.

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

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

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);