我有一个带有三个通用参数的接口,看起来像这样
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> {
...
}
答案 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);