'Convince TypeScript that Vue 3 template ref is available in onMounted

I am trying to work with an HTML canvas in a TypeScript Vue 3 component (Composition API).

The issue I am facing is that in an onMounted hook callback, TypeScript is telling me that the value of my template ref could be undefined even though I know it will not be by the time that onMounted fires. Is there anything I can do to convince TypeScript that it is not undefined and let me call methods on it?

Currently, I have wrapped it in an if-statement type guard style, but I am looking for a better way.

<script setup lang="ts">
import { onMounted, ref } from "vue";

const canvasElem = ref<HTMLCanvasElement>();

let ctx: CanvasRenderingContext2D | null;

onMounted(() => {
  if (canvasElem.value !== undefined) {
    ctx = canvasElem.value.getContext("2d");
  }
});
</script>

<template>
  <canvas ref="canvasElem" height="700" width="900"></canvas>
</template>


Solution 1:[1]

Use the non-null assertion operator:

onMounted(() => {
  ctx = canvasElem.value!.getContext("2d");
});

demo 1

Or optional chaining combined with nullish coalescing to default to null (to satisfy the type of ctx):

onMounted(() => {
  ctx = canvasElem.value?.getContext("2d") ?? null;
});

demo 2

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1