我有一个 Datum<T>
类型,其中 T
可以是 number
或 string
。 Datum
被收集为对象中的数组。我有一个 aggregateDatums
函数,它接受对象、带有 Datum
数组的键名,并返回一个数据。
export interface Datum<T extends string | number> {
key: T;
count: number;
}
const aggregateDatums = <
TKey extends string | number,
T extends { [k in K]: Datum<TKey>[] },
K extends keyof T
>(data: T, key: K): Datum<TKey>[] => {
return [];
};
const data = {
numeric: [{key: 1, count: 1}, {key: 2, count: 2}],
text: [{key: 'a', count: 1}, {key: 'b', count: 2}],
};
const aggregated = {
numeric: aggregateDatums(data, 'numeric'), // should be type Datum<number>[], but is Datum<string | number>[]
text: aggregateDatums(data, 'text'), // should be type Datum<string>[], but is Datum<string | number>[]
};
因为我传递了一个对象和一个包含数组的键,而不是直接包含 Datum
的数组,所以结果类型为 Datum<string | number>[]
。我的目标是与源数组中 Datum
的类型相对应的类型,因此 Datum<string>[]
或 Datum<number>[]
。关于如何实现这一目标的任何提示?
该示例已简化以仅显示问题。但如果我过度设计了可以更简单的类型,请告诉我。
此外,如果有人可以推荐有关 TypeScript 中高级类型的资源,我将不胜感激。不幸的是,大多数资源都是关于 Partial<T>
等类型的,而我知道您可以使用类型来实现高级魔法:-)
答案 0 :(得分:1)
const aggregateDatums = <
T extends { [k in K]: Datum<string | number>[] },
K extends keyof T
>(data: T, key: K): T[K] extends Datum<infer P>[] ? Datum<P>[] : never => {
throw 'implemented';
};