2015-04-16 3 views
6

Я искал Google в течение последнего часа, и я не нашел хорошего ответа или объяснения моей проблемы.Машинопись: Интерфейсы в типах соединений Вызывают ошибки с Instanceof

У меня есть переменная-член, определенная как тип объединения, примитива (числа) или интерфейса (KnockoutObservable), и я не могу использовать типы типов typeof или typeof без создания ошибки. Я использую обновление VS2013 4 с помощью TypScript 1.4. Я привел несколько примеров, чтобы продемонстрировать проблему:

class foo { 
    foo() {} 
} 

class bar { 
    bar() {} 
} 

interface baz { 
    baz(); 
} 

// This case breaks 
    var var1: number|foo; 

    if (typeof var1 === "number") { 
     var1 = 5; 
    } 
    // Generates error "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." 
    else if (var1 instanceof foo) { 
     var1.foo(); 
    } 

    // This also breaks, same error as above 
    if (var1 instanceof number) { 
     var1 = 5; 
    } 
    else if (var1 instanceof foo) { 
     var1.foo(); 
    } 

    // This case works 
    var var2: foo|bar; 

    if (var2 instanceof foo) { 
     var2.foo(); 
    } 
    else if (var2 instanceof bar) { 
     var2.bar(); 
    } 

    // This case breaks as well 
    var var3: foo|baz; 

    if (var3 instanceof foo) { 
     var3.foo(); 
    } 
    // Generates error: "Cannot find name 'baz'." 
    else if (var3 instanceof baz) { 
     var3.baz(); 
    } 

Мой вопрос: почему дела 1 и 3 прерываются? Мы создаем компоненты KnockoutJS, где параметр может быть наблюдаемым или примитивным. Поскольку KnockoutObservable - это интерфейс, это в значительной степени закрывает возможность использования типов union в нашем шаблоне; если мы хотим, чтобы параметр был либо, мы должны вернуться к использованию «any».

Некоторые из вещей, которые я нашел об этом (например, here), по-видимому, подразумевают, что это зафиксировано в 1.5. Может ли кто-нибудь дать мне оценку этого?

ответ

2

Обратите внимание, что присвоение переменной в любом месте тела функции «отключает» тип защиты от этой переменной, поэтому я удалил задания из этого примера.

В принципе, есть случай, который работает так, как ожидалось, случай, который должен работать, но не работает, и случай, который не работает, потому что для интерфейсов нет информации о времени выполнения. instanceof - это оператор JavaScript, который проверяет цепочку прототипов объекта, а не конструкцию TypeScript для операций типа.

var var1: number|foo; 
    // OK 
    if (typeof var1 === "number") { } 

    // Bug #2775 
    // https://github.com/Microsoft/TypeScript/issues/2775 
    if (var1 instanceof foo) { } 
    if (var1 instanceof number) { } 

    // OK 
    var var2: foo|bar; 
    if (var2 instanceof foo) { } 
    if (var2 instanceof bar) { } 

    // TypeScript does not have reflection; there is no 
    // value 'baz' to 'instanceof' at runtime. 
    if (var3 instanceof baz) { 
     var3.baz(); 
    } 

Ошибка x instanceof number также преднамеренно; нет значения времени выполнения number. Возможно, у вас возникнет соблазн написать x instanceof Number; это была бы ошибка (42 instanceof Number is false, а не true).

+0

Облом. Это делает типы профсоюзов значительно менее полезными, по крайней мере, для нашего использования. Я должен был проверить скомпилированный JS, по какой-то причине я думал, что Typcript добавлял некоторую информацию, чтобы включить отражение. Это накладывает реальное ограничение на то, что вы можете сделать с собственной JS-библиотекой, поскольку даже объекты (такие как KnockoutObservable) доступны в качестве интерфейсов через файл .d.ts или это просто известное ограничение? –

+0

Я борюсь с подобными проблемами. Я смотрю на объявление интерфейсов, у которых есть поля, которые являются объединением примитивного типа или наблюдаемого KO, так что модели просмотра и отправляемые сервером DTO могут использовать один и тот же интерфейс. Я рассматриваю использование ko.unwrap по параметрам метода, чтобы они могли рассчитывать на постоянное использование параметров. Это должно облегчить необходимость конкретных проверок типов. Может ли это помочь в этой ситуации? Вы видите недостаток этого подхода? –

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