TypeScript`groupBy`类型 [英] TypeScript `groupBy` typings

查看:57
本文介绍了TypeScript`groupBy`类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个 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`类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆