我经常需要按照属性对对象进行排序,因此我编写了以下简单的帮助程序:
static sort = <T extends {}>(list: Array<T>, field: keyof T, descending: boolean = true) =>
list.sort((a, b) => {
if (a[field] > b[field]) {
return descending ? -1 : 1;
}
if (a[field] < b[field]) {
return descending ? -1 : 1;
}
return 0;
});
我经常需要按照对象上的类似日期的属性对对象进行排序,但我收到的日期是以字符串形式呈现,格式为
"01-Apr-2018"
,因此我需要先将它们转换为日期。因此,我扩展了上面的内容:
static byDate = <T extends {}>(list: Array<T>, field: keyof T, descending: boolean = true) =>
list.sort((a, b) => {
if (new Date(a[field]).getTime() > new Date(b[field]).getTime()) {
return descending ? -1 : 1;
}
if (a[field] < b[field]) {
return descending ? 1 : -1;
}
return 0;
});
这导致了以下错误:
TS2345: 类型“T[keyof T]”的参数不能赋给类型“Date”的参数。
出现在 a[field]
和 b[field]
上。
跟踪 WebStorm / TypeScript Service 对所选择的 Date 实现,我注意到在 new Date("hello")
中,它从 lib.es5.d.ts
中选择了以下接口:
interface DateConstructor {
new(): Date;
new(value: number): Date;
new(value: string): Date; // THIS ONE (which I expect)
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
(): string;
readonly prototype: Date;
parse(s: string): number;
UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
now(): number;
}
然而在我的排序比较器中,它选择了从 lib.es2015.core.d.ts 中只包含以下内容的接口:
interface DateConstructor {
new (value: Date): Date;
}
尝试使用
new Date(a[field] as string)
或as Date
进行断言没有效果。我正在使用TypeScript 2.7.2版本(由我的当前Angular 6.0.9项目所需,无法更改)。
所以:
1.在这些上下文中,为什么
tsc
选择其中之一?2.如何断言我想要使用哪一个,或者至少在保持
field:keyof T
参数的同时让我的代码编译?