2016-11-22 4 views
2

Condidering этот примерМашинопись Союзы интерфейс и примитивным

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

Ошибка является: свойство «бар» не существует на тип «(fooInterface | строка)»

я делаю что-то неправильно, очевидно. Я хочу сказать в основном: value - это объект, реализующий fooInterface или строку.

Как я могу это сделать?

Спасибо

+0

Да, тип объединения - это правильный способ сказать это. Но если это строка, у нее не будет свойства 'bar', поэтому для доступа к ней будет ошибка. Что вы на самом деле пытаетесь сделать? – artem

+0

Если вы уверены, что это значение содержит значение fooInterface, вы можете убедить TypeScript вашей правды в значении '() .bar' или' (значение как fooInterface) .bar'. – 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 «s терпит неудачу, потому что он знает, что только что один неправильно.

Если вы не можете/не хотите этого делать, вы можете просто сказать компилятору, что знаете, что делаете, с утверждением типа (например, var definitelyFoo = (fooInterface) value), но лучше всего выбрать защитника.

+0

Имеет смысл, это заставляет мой код быть более надежным, спасибо. –

0

Если вы говорите, что value либо типа fooInterface или string, вы должны проверить тип, прежде чем вы можете работать с value. В вашем случае вы просто проверяете, value - string, используя typeof. Если нет, то это 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 (если были несколько интерфейсов или пользовательские типы).

Смежные вопросы