When trying to add a gradient to a line chart, I needed to get it's canvas. Before proceeding with the canvas I added a typecheck, however Vetur remarked that the "Object is possibly '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);
After researching I attempted to use the optional chaining operator to type check. This approach works, as no error is reported.
mounted() {
const canv = document.getElementById("line-chart") as HTMLCanvasElement;
const gradient = canv
?.getContext("2d")
?.createLinearGradient(0, 0, 0, canv.height);
I'm confused as to why the first approach doesn't work, since canv is a const, thus can't change. A type check should be enough.
Why is only the optional chaining working in this case?
The problem isn't with canv
. The compiler knows that canv
itself is not null
, but if you look at the return type for canv.getContext("2d")
, that is possibly null
:
HTMLCanvasElement.getContext(
contextId: "2d",
options?: CanvasRenderingContext2DSettings | undefined
): CanvasRenderingContext2D | null
That is what the "Object is possibly null" error is complaining about. You can fix that with optional chaining after that call, such as:
if (canv !== null && canv !== undefined) {
const gradient = canv.getContext("2d")?.createLinearGradient(0, 0, 0, canv.height)
}
Or you can do a more spelled-out type check:
if (canv !== null && canv !== undefined) {
const context = canv.getContext("2d");
if (context) {
const gradient = context.createLinearGradient(0, 0, 0, canv.height)
}
}
Or anything else that convinces the compiler that canv.getContext("2d")
will not be null
:
if (canv !== null && canv !== undefined) {
const gradient = (canv.getContext("2d") || { createLinearGradient: () => undefined })
.createLinearGradient(0, 0, 0, canv.height);
}