TypeScript联合类型接口和原始类型

4
考虑这个例子。
interface fooInterface {
    bar: any;
}
function(value: fooInterface | string) { 
    value.bar 
}

错误信息为:“在类型 '(fooInterface | string)' 上不存在属性 'bar'”

显然,我做错了什么。我的意思是:value 可以是实现 fooInterface 接口的对象或者是一个字符串。

我该怎么做呢?

谢谢。


是的,联合类型是正确的说法。但如果它是一个字符串,它就不会有 bar 属性,所以像那样访问它是错误的。你实际上想做什么? - artem
如果你确信value包含fooInterface值,你可以通过(<fooInterface>value).bar(value as fooInterface).bar来让TypeScript相信你的真实性。 - Misaz
2个回答

2

你不能使用value.bar,因为它不是绝对安全的。它可能是安全的(因为value可能是一个字符串),但编译器无法确定,除非它确定了,否则它不会让你使用.bar。你可能想要做的是使用类型保护

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.
}

您可以在TypeScript Playground中尝试这个链接。请注意,只有一个value.bar失败,因为它知道只有那个是错误的。
如果您不能/不想这样做,您可以使用类型断言告诉编译器您知道自己在做什么(例如var definitelyFoo = <fooInterface> value),但是警卫通常是更好的选择。

有道理,它强制我的代码更加健壮,谢谢。 - Adam Kettani

2
如果你说的这个“value”要么是“fooInterface”的类型,要么是“string”,那么在操作“value”之前,你必须先检查它的类型。在你的情况中,你只需使用“typeof”检查“value”是否是“string”类型。如果不是,“value”就是“fooInterface”的类型。请注意保留HTML标签。
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)或您自己的类型检查(如果有多个接口或自定义类型)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接