【问题标题】:Typescript Unions interface and primitiveTypescript Unions 接口和原语
【发布时间】:2017-04-05 17:28:51
【问题描述】:

考虑这个例子

interface fooInterface {
    bar: any;
}
function(value: fooInterface | string) { 
    value.bar 
}

错误是:类型'(fooInterface | string)'上不存在属性'bar'

我显然做错了什么。我想说的基本上是:value 要么是一个实现 fooInterface 的对象,要么是一个字符串。

我该怎么做?

谢谢

【问题讨论】:

  • 是的,联合类型是正确的说法。但是如果它是一个字符串,它就没有bar 属性,所以这样访问它是错误的。你到底想做什么?
  • 如果你确信值包含 fooInterface 值,你可以通过 (<fooInterface>value).bar(value as fooInterface).bar 让 TypeScript 相信你的真相。

标签: typescript interface typescript-typings


【解决方案1】:

您不能使用value.bar,因为它绝对不安全。它可能是安全的(因为 value 可能是一个字符串),但编译器并不确定这一点,除非确定,否则它不会让您执行 .bar。您可能想要做的是使用type guard:

if (typeof value !== "string") {
    value.bar
   // This compiles happily, because inside this if, value has
   // type 'fooInterface'. That's because TS now knows it isn't a string,
   // so *must* be a fooInterface.
}

你可以玩弄这个in the typescript playground:注意只有一个value.bar 失败了,因为它知道只有那个是错误的。

如果你不能/不想这样做,你可以只告诉编译器你知道你在用类型断言做什么(例如var definitelyFoo = <fooInterface> value),但是守卫通常是更好的选择。

【讨论】:

  • 有道理,它迫使我的代码更加健壮,谢谢。
【解决方案2】:

如果您告诉valuefooInterfacestring 类型,则必须先检查类型,然后才能使用value。在您的情况下,您只需使用typeof 检查value 是否为string。如果不是,则为fooInterface

interface fooInterface {
    bar: any;
}
function(value: fooInterface | string) {
    if (typeof value === "string") {
        // The compiler now knows that value is string
    }
    else {
        /* The compiler is smart and knows that the value
           must be of type fooInterface. */

        value.bar 
    }
}

在其他情况下,您将不得不使用 instanceof(用于检查对象是否是 typeof 特定类)或您的 own type checks(如果有多个接口或自定义类型)。

【讨论】:

    猜你喜欢
    • 2017-03-04
    • 2013-02-26
    • 2021-10-27
    • 1970-01-01
    • 2016-12-26
    • 2020-04-23
    • 1970-01-01
    • 2017-04-09
    相关资源
    最近更新 更多