Home > Net >  How to convince TypeScript by function that object is defined
How to convince TypeScript by function that object is defined

Time:10-05

Code:

public get scaleString(): string {
  const previewScale = !ObjectHelper.isNullOrUndefined(this.previewWidth) && !ObjectHelper.isNullOrUndefined(this.realWidth)
    // Object is possibly 'undefined'
    ? this.previewWidth / this.realWidth
    : 1;

  const scaleInPercent = previewScale * this.scale * 100;

  return `${scaleInPercent.toFixed(2)}%`;
}

ObjectHelper method:

public static isNullOrUndefined(v: object | string | boolean | number | null | undefined): boolean {
  return v === undefined || v === null;
}

What I get is a visual studio code / TypeScript error:

  • Object is possibly 'undefined'

enter image description here

One way would be to add if statements:

const previewScale = this.previewWidth !== undefined && this.previewWidth !== null && this.realWidth !== undefined && this.realWidth !== null
    ? this.previewWidth / this.realWidth
    : 1;

Is it possible to convince TypeScript that the upper function ObjectHelper.IsNullOrUndefined checked that already?

CodePudding user response:

You just need to make isNullOrUndefined a type guard:

  public static isNullOrUndefined(v: object | string | boolean | number | null | undefined): v is null | undefined {
    return v === undefined || v === null;
  }

Playground Link

Might I just suggest you can use == null as a replacement for the function x == null will be true if x is null or undefined. It's short, idiomatic to JS and TS understands it:

  public get scaleString(): string {
    const previewScale = this.previewWidth != null && this.realWidth != null
      // Object is possibly 'undefined'
      ? this.previewWidth / this.realWidth
      : 1;

    const scaleInPercent = previewScale * this.scale * 100;

    return `${scaleInPercent.toFixed(2)}%`;
  }

Playground Link

CodePudding user response:

Yes, you can. You can define the isNullOrUndefined like this

class ObjectHelper {
    static isNullOrUndefined(input: any): input is null | undefined {
        return [null, undefined].includes(input)
    }
}

TS Playground


Edit: Even better

you can define it using Extract as:

class ObjectHelper {
    static isNullOrUndefined<T>(input: T): input is Extract<T, null | undefined> {
        return input === null || input === undefined
    }
}

This way you'll be able to statically extract the null or undefined based on the input type

TS Playground

  • Related