getElementById 的类型检查仅适用于可选链接,不适用于类型检查

Type check for getElementById only works with optional chaining, not with type check

在尝试向折线图添加渐变时,我需要得到它 canvas。在继续 canvas 之前,我添加了一个类型检查,但是 Vetur 指出“对象可能是 'null'.Vetur(2531)”

  mounted() {
    const canv = document.getElementById("line-chart") as HTMLCanvasElement;
    if (canv !== null && canv !== undefined) {
      const gradient = canv
        .getContext("2d")
        .createLinearGradient(0, 0, 0, canv.height);

经过研究,我尝试使用可选的链接运算符进行类型检查。这种方法有效,因为没有报告错误。

  mounted() {
    const canv = document.getElementById("line-chart") as HTMLCanvasElement;
    const gradient = canv
      ?.getContext("2d")
      ?.createLinearGradient(0, 0, 0, canv.height);

我很困惑为什么第一种方法不起作用,因为 canv 是常量,因此无法更改。类型检查就足够了。

为什么在这种情况下只有可选链接起作用?

问题不在于 canv。编译器知道 canv 本身不是 null,但是如果你查看 canv.getContext("2d") 的 return 类型, 可能是 null:

HTMLCanvasElement.getContext(
  contextId: "2d", 
  options?: CanvasRenderingContext2DSettings | undefined
): CanvasRenderingContext2D | null

这就是“对象可能为空”错误所抱怨的。您可以在该调用之后使用可选链接修复该问题,例如:

if (canv !== null && canv !== undefined) {
    const gradient = canv.getContext("2d")?.createLinearGradient(0, 0, 0, canv.height)
}

或者您可以进行更详细的类型检查:

if (canv !== null && canv !== undefined) {
    const context = canv.getContext("2d");
    if (context) {
        const gradient = context.createLinearGradient(0, 0, 0, canv.height)
    }
}

或任何其他让编译器相信 canv.getContext("2d") 不会是 null:

if (canv !== null && canv !== undefined) {
    const gradient = (canv.getContext("2d") || { createLinearGradient: () => undefined })
        .createLinearGradient(0, 0, 0, canv.height);
}

Playground link to code