泛型函数参数限制为 T 的 属性

Generic function parameter restricted to a property of T

我有一个这样定义的 uniqBy 函数:

export function uniqBy<T>(a: T[], key: any): T[] {
    const seen = {};
    return a.filter(function (item) {
        if (item) {
            const k = key(item);
            return seen.hasOwnProperty(k) ? false : (seen[k] = true);
        } else {
            return false;
        }
    });
}

这会根据输入数组强类型化我的 return 值,但我也希望 key 参数是强类型的,这样如果我尝试传入时会出现编译时错误T 上不存在的 属性。 当前用法示例:

uniqArray = uniqBy(this._checkups, x => x.CatDescription);

_checkups 是以下数组:

export interface Checkup {
  id: string;
  CatDescription: string;
  ProcessTitle: string;
  MsgProcessID: number;
  MsgDate: string;
  MsgStatus: number;
  MsgText: string;
  MsgAction: string;
  MsgEntityID: string;
  MsgEntity: string;
}

如果尝试执行以下操作,我会喜欢它:

uniqArray = uniqBy(this._checkups, x => x.NonExistantProperty);

给我一个编译时错误(以及 属性 完成时的 IntelliSense)。我将如何在参数中定义 key 以便执行此操作?

这将 return 一个只有唯一值 CatDescription 的项目数组(在重复的情况下取第一个带有 CatDescription 的对象)。

我不知道这叫什么,它不是用于过滤的 Predicate<T> 而 return 是一个布尔值。

似乎作为第二个参数,你传递了回调,但你没有它的类型,所以你只需给它一个类型 (val: T) => T[keyof T]

export function uniqBy<T>(a: T[], key: (val: T) => T[keyof T]): T[] {
    const seen = {};
    return a.filter(function (item) {
        if (item) {
            const k = key(item);
            return seen.hasOwnProperty(k) ? false : (seen[k] = true);
        } else {
            return false;
        }
    });
}

然后添加不存在的密钥会报错

uniqArray = uniqBy<Checkup>(this._checkups, x => x.NonExistantProperty);