2016-07-06 1 views
2

Это SSCCE. Код ниже:как выполнить динамический тест типа с типом интерфейса?

// @flow  
'use strict'; 

declare interface ICat { 
    purr(): string; 
} 

class Animal { 
    askToBeStrokedAsACat() { 
     strokeAsACat(this); // Flow complains here 
    } 
} 

function strokeAsACat(a: ICat) { 
    a.purr(); 
} 


class Cat extends Animal { 
    purr() { 
     return 'purr'; 
    } 
} 

const cat = new Cat(); 
cat.askToBeStrokedAsACat(); 

... Результаты в Flow жалующиеся на вызов функции из strokeAsACat. Жалобы (отредактированная для краткости):

property `purr` of ICat not found in class Animal 

жалоба является разумной и понято.

Согласно тому, что написано на dynamic type tests я должен быть в состоянии просто сделать следующее:

class Animal { 
    askToBeStrokedAsACat() { 
     if (this instanceof ICat) 
      strokeAsACat(this); 
    } 
} 

... вместо этого выше не с:

ICat. type referenced from value position 

Plus, поскольку интерфейсы transpiled ICat не доступен во время работы, поэтому при работе с ним не выполняется:

ReferenceError: ICat is not defined 

Таким образом, единственный способ убедиться в том, что this ручка в этой точке является ICat -как объект должен сделать следующее:

class Animal { 
    askToBeStrokedAsACat() { 
     if (this instanceof Cat) 
      strokeAsACat(this); 
    } 
}  

... но это nominal, not structural typing и поражения цели с помощью интерфейс ICat как если бы я добавить еще пару ICat-like классов я должен написать свой динамический тест типа, как:

(this instanceof Cat) || (this instanceof BobCat) || (this instanceof Lynx) 

так что мои вопросы:

  1. Есть ли способ выполнить структурный динамический тест типа для interface?
  2. есть ли другой способ эффективно отключить жалобы Flow на эту конкретную строку?

Моя Flow версия:

$ npm ls --depth 0 | grep flow-bin 
├── [email protected] 

ответ

1

есть способ, чтобы выполнить структурный тест динамического типа для интерфейса

Нет, это невозможно. Вы можете проверить, что объект имеет свойство, и это функция, но как вы узнаете, что это подпись во время выполнения?

Вам это редко нужно. Например, в вашем коде вы можете оставить askToBeStrokedAsACat пустым на Animal и переопределить его в подклассе Cat.

+0

Это SSCCE, поэтому да в этом конкретном примере вы можете поместить 'askToBeStrokedAsACat' в подкласс« Cat », как вы говорите, но в реальном случае (где это было уменьшено) это было необходимо для кода оставаться в базовом классе. Что еще более важно, я не думаю, что ваши рассуждения о том, «как вы знаете его подпись во время выполнения», верны. Все аннотации потока передаются во время выполнения, но это не останавливает поток от всех видов полезных проверок типа. –

+0

Поток анализирует конструкции времени выполнения, чтобы доказать, что код безопасен и будет выполняться, как ожидалось. Если во время выполнения нет возможности проверить что-либо, Flow не может сделать вывод, что то, что вы делаете, безопасно. – vkurchatkin

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