我想编写一个 groupBy 函数,到目前为止,类型系统对我的工作并不满意.
I want to write a groupBy function, so far the type system is not so happy with my work.
export function group< T extends object, K extends (keyof T & string), R = T[K] extends string ? string : never >( data: T[], groupBy: keyof T ): { [group: R]: T[] }我得到的第一个错误是 {[group:R]:T []} 中的 R 不是 string 或数字.
The first error that I got is that R in { [group: R]: T[] } is not string or number.
对于的数据集,签名实际上根本不起作用
The signature actually doesn't work at all for the data set of
group([{ name: 'Johnny Appleseed', age: 17 }], 'name') // R should be string group([{ name: 'Johnny Appleseed', age: 17 }], 'age') // R should be never但是,两个 R 都是从不,而 K 都是"name" |年龄"
However, both R is never while K is "name" | "age"
我必须使用 group< {name:string,age:number},'name'> 来手动缩小类型参数,以使 R 为字符串.
I have to manually narrow down type parameter with group<{name: string, age: number}, 'name'> to make R be string.
推荐答案索引签名必须为 string 或 number .没有联合类型,没有泛型类型,除了 string 或 number 之外,别无其他.
An index signature must be either string or number. No union types, no generic types nothing else will do except string or number.
如果您使用两个函数签名,一个仅接受 string 键,而另一个仅接受 number 键,我们仍然可以实现您想要的行为:
We can still achieve the behavior you want if you use two function signatures, one that accepts only string keys and the other that only accepts number keys:
export declare function group<T extends Record<K, string>, K extends string>(data: T[], groupBy: K): { [group: number]: T[] } export declare function group<T extends Record<K, number>, K extends string>(data: T[], groupBy: K): { [group: string]: T[] } let groupByString = group([{ name: 'Johnny Appleseed', age: 17 }], 'name') let groupByNumber = group([{ name: 'Johnny Appleseed', age: 17 }], 'age')更多推荐
TypeScript`groupBy`类型
发布评论