提问人:Luke 提问时间:7/12/2023 最后编辑:Luke 更新时间:7/18/2023 访问量:126
D3 .extent() 拒绝打字稿中的日期数组
D3 .extent() rejecting array of Dates in typescript
问:
我正在努力在打字稿中使用 d3 的 .extent() 函数。
我这里有一些代码,可以创建日期之外的 Date 对象
const dates:(Date | null)[] = data.map(row => d3.timeParse("%Y-%m-%d")(row.Date))
当我控制台记录日期变量时,它看起来像这样
[Sat Jun 24 2023 00:00:00 GMT-0700 (Pacific Daylight Time), Sat Jun 24 2023 00:00:00 GMT-0700 (Pacific Daylight Time), Fri Jun 23 2023 00:00:00 GMT-0700 (Pacific Daylight Time), Fri Jun 23 2023 00:00:00 GMT-0700 (Pacific Daylight Time), Fri Jun 23 2023 00:00:00 GMT-0700 (Pacific Daylight Time), ...]
因此,我知道我的日期变量充满了 Date 对象,就像预期的那样......
但是,当我尝试使用 d3.extent() 函数查找最高和最低日期时
const xScale = d3
.scaleTime()
.domain(d3.extent(dates))
Argument of type '[undefined, undefined] | [string, string]' is not assignable to parameter of type 'Iterable<Date | NumberValue>'.
不过,我对为什么会这样感到困惑,因为我的日期变量实际上完全是日期,而不是错误中表达的“[未定义,未定义] |[字符串,字符串]'。
我经过的东西有什么问题?我应该如何将日期传递给打字稿中的 extent() 函数?
答:
筛选实例是一种很好的方法,但您可以得到:
.null
Type '(Date | null)[]' is not assignable to type 'Date[]'. Type 'Date | null' is not assignable to type 'Date'. Type 'null' is not assignable to type 'Date'
这是因为即使在筛选操作之后,TypeScript 仍在考虑数组中值的可能性。null
应在 filter 函数中包含类型谓词。这明确告诉 TypeScript 筛选器的结果将仅包含对象,而不包含值。date is Date
Date
null
const dates:(Date)[] = data
.map(row => d3.timeParse("%Y-%m-%d")(row.Date))
.filter((date): date is Date => date !== null);
这确实创建了一个过滤器函数,该函数不仅检查日期是否不是,而且还使用类型保护来告诉 TypeScript 通过此过滤器的每个项目都是 .
(另请参阅 Shreejit Rajbanshi 的“类型谓词:在 Typescript 中过滤数组”null
Date
)
OP 使用:
dates: (Date)[]
:在筛选操作 () 之后,确保过滤掉所有值。因此,您只剩下一个对象数组。因此,您需要键入 as 而不是 。filter((date): date is Date => date !== null)
null
Date
dates
Date[]
(Date | null)[]
紧随其后的是:
const xScale = d3
.scaleTime()
.domain(d3.extent(dates) as unknown as [Date, Date]);
我提议的原始代码用于告诉 TypeScript 信任我们,域将是两个对象的元组。as [Date, Date]
Date
这是一个类型断言,它不会改变代码的实际值或操作,而只是通知 TypeScript 类型。这不会保护您在运行时免受未定义值的影响,它纯粹用于 TypeScript 的静态类型检查。因此,为什么我们在过滤器操作期间之前进行了检查。as [Date, Date]
null
null
但 OP 使用了:
dates as unknown as Date[]
:当 TypeScript 不能直接从一个类型断言到另一个类型时,使用此构造,但我们作为开发人员知道这是可能的。通过强制转换为 first,您基本上绕过了 TypeScript 的类型检查,然后将其重新断言为 .unknown
Date[]
评论