Рассмотрим интерфейс машинопись с двумя реализациями:Компилятор TypeScript не применяет параметр типа при реализации универсального интерфейса?
interface IFoo {}
class FooA implements IFoo {}
class FooB implements IFoo {}
Далее рассмотрим общий интерфейс, который принимает реализацию IFoo
в качестве параметра типа:
interface IFooHandler<F extends IFoo> {
handle(foo: F): string
}
Теперь давайте реализовывать интерфейс IFooHandler
с конкретным применение IFoo
в качестве параметра типа:
class FooAHandler implements IFooHandler<FooA> {
handle(foo: FooB): string {
return "Hello, Foo A!";
}
}
Это прекрасно компилируется, используя tsc
в версии 2.0.3. Так вот мой вопрос: Почему делает это компилировать?
Обратите внимание, что я использовал FooB
в качестве параметра в функции handle()
. Я бы предположил, что этот код вызовет ошибку компиляции, поскольку интерфейс IFooHandler<F>
предписывает, что метод handle
должен принимать параметр типа F
(так, в случае IFooHandler<FooA>
, типа FooA
- и не FooB
).
Я не мог найти что-либо по этому поведению в документации машинописи. Является ли это поведение преднамеренным, и если да, то в чем его причина? Или я использую эту функцию неправильно?
Для сравнения, реализуя тот же самый пример в Java (исключая код, так как это очень похоже) дает (ожидаемый) компиляции ошибка:
FooAHandler.java:1: error FooAHandler is not abstract and does not override abstract method handle(FooA) in IFooHandler
Это обсуждается несколько раз в FAQ - https: // github.com/Microsoft/TypeScript/wiki/FAQ#what-is-structural-typing и https: // github.com/Microsoft/TypeScript/wiki/FAQ # when-and-why-are-classes-rated и –
Также в основном дубликат http://stackoverflow.com/questions/32106253/why-does-typescript-implicitly-convert- между-несвязанными классами –
@RyanCavanaugh, спасибо за ссылку. Ой, я не могу поверить, что я пропустил ** буквально первый вопрос ** в FAQ. Во всяком случае, это поведение имеет для меня больше смысла! Спасибо за ваш комментарий. – helmbert