返回 Typescript 中两种类型之一的方法

Mic*_*way 5 typescript

我有以下方法,如果之前已注册,则应该返回组件对象

/**
 * 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];
}
Run Code Online (Sandbox Code Playgroud)

一切都编译并运行良好,但我的编辑器抛出以下警告......

Property 'x' does not exist on type 'boolean | ComponentInterface'
Run Code Online (Sandbox Code Playgroud)

当我尝试跑步时...

const oPositionComponent = oEntity.getComponent('position');
console.log(oPositionComponent.x);
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来编写此内容,以便我的编辑知道我想要实现的目标?


解决方案

好吧,因为我实际上是在上一步中检查组件是否存在,所以我只是对返回值进行了类型转换......

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

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

wei*_*dan 4

由于它可能返回,false编译器假设 oPositionComponent.x 在这种情况下可能会失败。您可以断言类型(如果您确定您会获得组件并且不是 false:

console.log((<ComponentInterface>oPositionComponent).x);
Run Code Online (Sandbox Code Playgroud)

但在生产质量代码中,您应该通过类型缩小来处理可能的错误返回:

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");
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,由于 JSX,使用 `&lt;Type&gt;variable` 的类型转换是遗留的。使用“变量作为类型”。 (3认同)
  • @MadaraUchiha 这不是遗产。在“.ts”文件中,您可以使用任一语法,并且两者都不被弃用。在 `.tsx` 文件中,必须使用 `as`。就我个人而言,我认为“value as Type”读起来稍好一些,但“&lt;Type&gt;value”绝不是遗留的。 (3认同)