在axis.tickFormat() 中使用d3.timeFormat 时出现TypeScript 错误

gpb*_*lio 6 d3.js typescript

此代码适用于 JavaScript:

var timeFormat = d3.timeFormat("%M:%S");
var yAxis = d3.axisLeft(y).tickFormat(timeFormat)
Run Code Online (Sandbox Code Playgroud)

但是 TypeScript 中的这段代码不起作用:

const yAxis = d3.axisLeft(y).tickFormat(d3.timeFormat("%M:%S"));
Run Code Online (Sandbox Code Playgroud)

function timeFormat(specifier: string): (date: Date) => string 返回给定字符串说明符的新格式化程序。返回的函数格式化指定的日期,返回相应的字符串。

默认语言环境中 locale.format (TimeLocaleObject.format) 的别名。

@param 说明符 — 日期格式的说明符字符串。

错误是

'(date: Date) => string' 类型的参数不能分配给 'null'.ts(2345) 类型的参数

alt*_*lus 10

传递给的函数传递.tickFormat()了第二个参数,表示刻度标签的索引。该方法的类型定义如下所示:

tickFormat(format: (domainValue: Domain, index: number) => string): this;
Run Code Online (Sandbox Code Playgroud)

类型定义d3.timeFormat(),而另一方面,如下所示:

export function timeFormat(specifier: string): (date: Date) => string;
Run Code Online (Sandbox Code Playgroud)

如您所见,这将返回一个将Date对象映射到字符串的函数。这个函数没有第二个参数,因此有错误。

为了解决这个问题,您可以显式转换 返回的函数类型d3.timeFormat()以匹配 期望的类型.tickFormat()

.tickFormat(d3.timeFormat("%M:%S") as (dv: number | { valueOf(): number; }, i: number) => string)
Run Code Online (Sandbox Code Playgroud)

这没有任何副作用,因为您可以安全地忽略未使用的第二个参数,同时仍然告诉编译器您知道自己在做什么。

  • 谢谢,尽管这会导致“将类型 '(date: Date) => string' 转换为类型 '(dv: number | { valueOf(): number; }, i: number) => string” 可能是一个错误,因为两者都不是类型与其他类型充分重叠。如果这是故意的,请先将表达式转换为“未知”。` ...打字稿,叹息 (2认同)

cjd*_*jds 5

有一个更简单的现代解决方案

const yAxis = d3.axisLeft<Date>(y).tickFormat(d3.timeFormat("%M:%S"));
Run Code Online (Sandbox Code Playgroud)

适用于 d3v4