gpt4 book ai didi

typescript - 泛型:TS2345 'T[keyof T]' 类型的参数不可分配给 'Date' 类型的参数,其中

转载 作者:搜寻专家 更新时间:2023-10-30 21:17:16 26 4
gpt4 key购买 nike

我经常需要按属性对对象进行排序,因此我编写了以下简单的帮助程序:

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: Argument of type 'T[keyof T]' is not assignable to parameter of type 'Date'

a[field]b[field]

跟踪 WebStorm/TypeScript 服务对所选日期的实现,我注意到在 new Date("hello") 中,它从 lib.es5.d.ts 中选择了以下接口(interface):

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 项目需要并且无法更改)。

所以:

  1. 为什么 tsc 在这些情况下选择其中之一?

  2. 我如何断言我希望它使用哪一个,或者至少让我的代码在保持 field: keyof T 参数的情况下进行编译?

最佳答案

我现在无法在 2.7.2 上进行测试,但主要问题是 TypeScript 不相信 a[field]必然是 string .这是有道理的,因为 a是泛型 T , 和 field类型为 keyof T , 所以它只知道 a[field]T[keyof T] .那可能string ,或者它可能是你不能调用的东西 new Date()上。

如果你确定你只会调用 byDatea[field]的地方是 string , 然后你可以改变泛型是这样的:

static byDate = <K extends keyof any, T extends Record<K, string>>(
list: Array<T>,
field: K,
descending: boolean = true
) => { ... }

这应该会使错误消失...它现在知道 a[field]类型是 T[K] , 其中T延伸Record<K, string> ,也称为 {[P in K]: string} ,或“一个对象,其键位于 K 中,其值为 string ”。所以T[K]延伸string它很开心。

以上应该适用于 TypeScript 2.7.2,但如果您遇到问题请告诉我。

希望对您有所帮助。祝你好运!

关于typescript - 泛型:TS2345 'T[keyof T]' 类型的参数不可分配给 'Date' 类型的参数,其中 <T extends {}>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51621243/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com