Search code examples
typescriptnull-check

Null-check for inherited member in TypeScript?


abstract class Base {
  protected id: number | null = null;

  init(id: number) {
    this.id = id;
  }

  isIdSet(_ = this.id): _ is null | never {
    if (this.id === null) throw new Error(ERROR_NO_ID);
    else return false;
  }
}

class Foo extends Base {
  private fetch(id: number) { ... }
  
  get(): Observable<string> {
    if (this.isIdSet()) {
      return this.fetch(this.id); // TS2322: Type 'number | null' is not assignable to type 'number'.
    }
  }
}

Solution

  • The idea was to put he null-check and throw into a function to get rid of duplicate if statements

    You can do this in the base class with a custom getter that checks if this.m_id is defined and throws an error otherwise, essentially forcing the init method to be called before accessing id.

    class Base {
        private m_id: number | null = null;
    
        protected get id(): number {
            if(this.m_id === null){
                throw new Error(`Id is not defined`);
            }
            return this.m_id;
        }
    
        public init(a_id: number): void {
            this.m_id = a_id;
        }
    }
    
    
    class Foo extends Base {
        private fetch(a_id: number): string {
            return a_id.toString();
        }
    
        public get(): string {
            return this.fetch(this.id);
        }
    }
    

    Playground