简体   繁体   中英

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);
});

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");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM