【发布时间】:2019-01-08 07:32:27
【问题描述】:
我经常要按属性对对象进行排序,所以我写了下面这个简单的助手:
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]”类型的参数不可分配给“日期”类型的参数
在a[field] 和b[field] 上。
跟踪WebStorm/TypeScript Service对选择的日期的实现,我注意到在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;
}
但在我的排序比较器中,它选择了the interface from 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 项目需要并且无法更改)。
所以:
为什么
tsc在这些情况下会选择其中一个?如何断言我希望它使用哪一个,或者至少在保持
field: keyof T参数的同时让我的代码编译?
【问题讨论】:
标签: typescript generics ecmascript-6 typescript2.0 ecmascript-5