javascript - 无法从联合类型访问参数 (TypeScript)

标签 javascript typescript

为什么不能像这样访问联合类型中的属性:

export interface ICondition {
  field: string
  operator: string
  value: string
}

export interface IConditionGroup {
  conditions: ICondition[]
  group_operator: string
}

function foo(item: ICondition | IConditionGroup) {
  if(typeof item.conditions === "undefined") { // does not work
    let field = item.field; // does not work
    ///.. do something 
  } else {
    let conditions = item.conditions; // does not work
    /// .. do something else
  }
}

我收到这些错误:

error TS2339: Property 'conditions' does not exist on type 'ICondition | IConditionGroup'.
error TS2339: Property 'conditions' does not exist on type 'ICondition | IConditionGroup'.
error TS2339: Property 'field' does not exist on type 'ICondition | IConditionGroup'.

但我必须转换类型才能让它工作 - 就像这样:

function foo2(inputItem: ICondition | IConditionGroup) {
  if(typeof (<IConditionGroup>inputItem).conditions === "undefined") {
    let item= (<ICondition>inputItem);
    let field = item.field;
    ///.. do something 
  } else {
    let item= (<IConditionGroup>inputItem);
    let conditions = item.conditions;
    /// .. do something else
  }
}

我知道类型信息在 JS 中丢失了,那么为什么我必须在 TS 中显式转换它?

最佳答案

Typescript 使用 Type Guards 处理这个问题,通常很简单:

if (typeof item === "string") { ... } else { ... }

或者

if (item instanceof MyClass) { ... } else { ... }

但在您的情况下,因为您使用的是不可能的接口(interface),所以您需要创建自己的 User-Defined Type Guards :

function isConditionGroup(item: ICondition | IConditionGroup): item is IConditionGroup {
    return (item as IConditionGroup).conditions !== undefined;
}

function foo(item: ICondition | IConditionGroup) {
    if (isConditionGroup(item)) {
        let conditions = item.conditions;
        // do something
    } else {
        let field = item.field;
        // do something else
    }
}

( code in playground )

你也可以在没有类型保护的情况下这样做:

function foo(item: ICondition | IConditionGroup) {
    if ((item as IConditionGroup).conditions !== undefined) {
        let conditions = (item as IConditionGroup).conditions;
        // do something
    } else {
        let field = (item as ICondition).field;
        // do something else
    }
}

但这太冗长了,因为您需要键入 assert item 3 次而不是一次。

关于javascript - 无法从联合类型访问参数 (TypeScript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39127929/

相关文章:

angular - AngularFire2 : how to handle $key 中的类

javascript - Ajax 调用后显示成功消息的问题

javascript - 使用 Bootstrap slider 获取范围值

typescript - 如何包含排除文件夹中的文件/子文件夹?

TypeScript 文件中的 JavaScript 智能感知

c# - 将值从 Angular 服务应用程序发送到 C# 后端 Controller

javascript - 现代 ExtJS 6 6.2 isValid() 不是函数

javascript - 开放层 3 : Trying to add image underlay to a vector layer

javascript - yadcf 过滤器不工作

arrays - TypeScript 函数数组