首页 > 解决方案 > 数组中每个通用项的一致类型

问题描述

所以,我的想法是有一个这样的通用项目数组:

interface Item<T extends {} = {}> {
  out: () => T;
  in: (data: T) => void;
};

但是,在定义数组时,我唯一能想到的就是:

type ItemArray<T extends {} = {}> = Item<T>[];

那么问题是如果我这样定义数组,数组的每个项目都具有相同的类型,而我想要做的是:

interface A { n: number }
interface B { s: string }
const arr = [
  { out: () => { n: 1 }, in: (data: A) => void },
  { out: () => { s: 'txt' }, in: (data: B) => void },
];

如您所见,数组中每个项目的outin成员具有一致的类型,但数组本身是通用的。

另外,我无法将数组定义为,ItemArray<A | B>因为那时它抱怨 A 没有 B 的所有成员,等等。

我也不想这样做,ItemArray<A & B>因为在访问每个成员时,它应该接受什么样的参数没有帮助(它给了我所有类型的联合)。

我想做一些更像...

const arr = [
  item0 as Item<A>, // the hint of "as Item<Type>" shouldn't even
  item1 as Item<B>, // be needed if TS infers it properly
];

// if I do this, TS should know that out0 is type A
const out0 = arr[0].out();
// and if I do this, out1 should be inferred as B
const out1 = arr[1].out();

但我还没有找到让 TypeScript 根据out成员的返回类型或函数的接受类型自动推断每个项目的类型的in方法。

有什么建议吗?

标签: typescripttypescript-generics

解决方案


如果您希望array[0]and的类型array[1]不同,则array需要有一个元组类型[Type0, Type1]而不是一个数组类型,如(Type0 | Type1)[].

幸运的是,很容易让 Typescript 从数组文字而不是数组类型推断元组类型:只需添加as const. 例如:

const array = [1, 'foo'] as const;

let zero: number = array[0];
let one: string = array[1];

推荐阅读