这是一个操场,代码是:
const groupBy = <T, K extends keyof T>(o: T[], selector: (item: T) => T[K]): Record<string, T[]> => {
const ret: Record<string, T[]> = {};
for (const element of o) {
const key = (selector(element) as unknown) as string;
Object.assign(ret, { [key]: (ret[key] || []).concat(element) });
}
return ret;
};
const array = [
{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2' },
{ key: 'key1', value: 'value3' },
];
console.log(groupBy(array, (row) => row.key)['key1'])
我不得不用钥匙来做这件事:
const key = (selector(element) as unknown) as string;
有办法绕过这个吗?
您可以通过交集运算符重新定义selector
以返回T[K] & string
const groupBy = <T, K extends keyof T>(o: T[], selector: (item: T) => T[K] & string): Record<string, T[]> => {
// ...
for (const element of o) {
// ...
// no type assertion needed anymore
Object.assign(ret, { [key]: (ret[key] || []).concat(element) });
}
return ret;
};
游乐场
之前需要类型断言(selector(element) as unknown) as string;
的原因是key
得到了类型T[K]
。TypeScript无法进一步解析T[K]
,因此它不能用作对象文字的键。触发以下错误:
计算的属性名称的类型必须为"string"、"number"、"symbol"或"any"。(2464(