Why is the inferred type in Vscode like this ?

Advertisements

I have a class:

class Cancelled {
    static cancelled = new Cancelled()
    static from<T>(v: T | undefined) {
        return v ?? this.cancelled
    }
}

Why Vscode infers the type of the result of the function Cancelled.from as only Cencelled instead of T | Cancelled?

>Solution :

Why Vscode infers the type of the result of the function Cancelled.from as only Cencelled instead of T | Cancelled?

Because at the moment, Cancelled doesn’t define any non-static properties. That means it’s compatible with almost anything. In the following code, the only lines that complain are the null and undefined:

const a: Cancelled = true;
const b: Cancelled = {};
const c: Cancelled = "hi";
const d: Cancelled = 3;
const e: Cancelled = new Date();
const f: Cancelled = () => {};
const g: Cancelled = Symbol('foo');
const h: Cancelled = null; // Error
const i: Cancelled = undefined; // Error

But your code excludes null and undefined, so we can ignore them. What we’re left with is that Cancelled is a broader type than NonNullable<T>. Everything that is a NonNullable<T> is also a Cancelled, so saying Cancelled | NonNullable<T> is redundant. VS code shows the simpler type.

Playground Link

As soon as you add even one property to Cancelled, this is no longer the case, and the return type will be inferred to be Cancelled | NonNullable<T>.

class Cancelled {
    static cancelled = new Cancelled()
    static from<T>(v: T | undefined) {
        return v ?? this.cancelled
    }

    foo: string = 'bar'
}

Playground link

Leave a ReplyCancel reply