-1

我正在尝试约束键,因此它只能引用 TItem 的数字或日期键。

public static indexOfMin<TItem extends object | number | Date>(array: Array<TItem>, key?: keyof TItem): number {
    let min: number = Number.MIN_SAFE_INTEGER;
    let index: number = -1;
    const length = array.length;
    for (let i = 0; i < length; i++) {
        const value = Number(isNullOrUndefined(key) ? array[i] : array[i][key]);
            if (value < min) {
                min = value;
                index = i;
            }
     }
    return index;
    }

interface IPerson {
    name: string;
    age: number;
    dob: Date;
}

indexOfMin(new Array<IPerson>(), 'name'); // error as name is string.
indexOfMin(new Array<IPerson>(), 'age'); // ok are age is number.
indexOfMin(new Array<IPerson>(), 'dob'); // ok are age is Date.
4

1 回答 1

0

您可以通过添加条件类型来做到这一点。它看起来有点复杂,但可以完成工作。TypeScript 文档章节中有一个关于分布式条件类型的类似示例。

这是一个示例,您可以如何定义仅选择数字和日期的属性名称的类型:

type NumberOrDatePropertyNames<T> = { [K in keyof T]: T[K] extends number | Date ? K : never }[keyof T];

K 是 T 类型的键。然后您将 T[K] 限制为具有键 K 的实际属性的类型,如果属性是数字或日期则返回键 K 的条件类型,否则它匹配never 这意味着它被忽略了。

然后可以将您的函数参数更改为使用此类型,并且键将仅限于数字和日期属性。

public static indexOfMin<TItem extends object | number | Date>(array: Array<TItem>, key?: NumberOrDatePropertyName<TItem>): number {
    let min: number = Number.MIN_SAFE_INTEGER;
    let index: number = -1;
    const length = array.length;
    for (let i = 0; i < length; i++) {
        const value = Number(isNullOrUndefined(key) ? array[i] : array[i][key]);
            if (value < min) {
                min = value;
                index = i;
            }
     }
    return index;
}
于 2019-07-09T22:24:31.567 回答