2016-11-22 99 views
2

Condidering这个例子打字稿工会接口和原始

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

的错误是:住宅“酒吧”上不存在类型“(fooInterface |字符串)”

我做错了明显。我想说的基本上是:value是一个实现fooInterface或字符串的对象。

我该怎么做?

谢谢

+0

是的工会类型是正确的说法。但是,如果它是一个字符串,它不会有'bar'属性,所以这样访问它是一个错误。你究竟在做什么? – artem

+0

如果您确信该值包含fooInterface值,则可以通过'( value).bar'或'(value as fooInterface).bar'来说明TypeScript的真相。 – Misaz

回答

2

不能使用value.bar,因为它不是绝对安全。它可能是安全的(因为值可能是一个字符串),但编译器并不知道这一点,除非它确定,否则它不会让你做.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),但是一个守护者通常是更好的选择。

+0

有道理,它强制我的代码更健壮,谢谢。 –

0

如果,你是在告诉value要么fooInterface型或string的,你必须检查的类型,然后才能与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(如果有多个接口或自定义类型)。