Michael Dilloway
Michael Dilloway

Reputation: 305

Method that returns one of two types in Typescript

I have the following method that is supposed to return a component object if it's previously been registered

/**
 * Retrieve a component
 * @param       string      sComponentName      The name of the component to look for
 * @return      ComponentInterface | boolean
 */
public getComponent(sComponentName: string): boolean | ComponentInterface {
    if(!this.hasComponent(sComponentName)) {
        return false;
    }

    return this.components[sComponentName];
}

Everything compiles and runs fine but my editor is throwing the following warning...

Property 'x' does not exist on type 'boolean | ComponentInterface'

when I try to run...

const oPositionComponent = oEntity.getComponent('position');
console.log(oPositionComponent.x);

Is there a better way of writing this so that my editor knows what I'm trying to achieve?


Solution

Ok, so since I was actually checking the existence of the component in the previous step I just type-casted the return value...

aEntities = aEntities.filter((oEntity) => {
    return oEntity.hasComponent('position');
});

aEntities.forEach((oEntity) => {
    const oPositionComponent = <ComponentInterface> oEntity.getComponent('position');
    this.context.translate(oPositionComponent.x, oPositionComponent.y);
});

Upvotes: 5

Views: 3984

Answers (1)

weirdan
weirdan

Reputation: 2632

Since it may return false compiler assumes oPositionComponent.x may fail in this case. You may assert the type (if you're sure you'd get the component and not false:

console.log((<ComponentInterface>oPositionComponent).x);

But in production-quality code you should deal with possible false returns via type narrowing :

if (oPositionComponent instanceof ComponentInterface) { // this will only work with classes, not interfaces (?)
    console.log(oPositionComponent.x);
} else { // this must be false
    console.log("component is not registered");
}

Upvotes: 4

Related Questions