Search code examples
typescripttypestypeguards

User defined type guards without passing a parameter


Let's say I have these classes:

export abstract class AbstractSubjectChild<T extends Subject>
{
    protected parent: T | undefined;

    public hasParent()
    {
        return this.parent != null;
    }

    public setParent(parent: T): void
    {
        this.parent = parent;
    }

    public getParent(): T | undefined
    {
        return this.parent;
    }
}

class Child extends AbstractSubjectChild<Post>
{   
}

And I want to do something like this:

const child = new Child();

if (child.hasParent()) {
    const post: Post = child.getParent();
}

Is there a way to tell TS compiler to infer the type based on hasParent() result without having to explicitly use as Post everywhere?


Solution

  • export abstract class AbstractSubjectChild<T extends Subject>
    {
        protected _parent?: T;
    
        public set parent(parent: T): void
        {
            this._parent = parent;
        }
    
        public get parent(): T | undefined
        {
            return this._parent;
        }
    }
    

    write your class that way and you can do:

    if (child.parent) {
      const post = child.parent;
      // everywhere in this block scope is now aware of the type of post
    }