Рассмотрим следующий общий интерфейс:
interface Extractor<T> {
extractCandidate(): T;
process(candidate: T): T;
}
Концептуально каждая реализация Extractor
отвечает за извлечение объектов определенного типа из некоторого источника данных. Потребитель Extractor
может извлечь объект-кандидат, используя extractCandidate()
, или, при наличии любого кандидата, выполнить над ним некоторую дальнейшую обработку, чтобы получить более усовершенствованную версию объекта, используя process()
.
Теперь предположим, что я реализую Extractor
для класса MyClass
, например:
class MyClass {
a: string;
b: string;
}
class MyExtractor implements Extractor<MyClass> {
extractCandidate() {
//Some dummy logic
return new MyClass();
}
process(candidate) {
//Some dummy logic
let res = new MyClass();
res.a = candidate.a;
return res;
}
}
Теперь предположим, что я создаю экземпляр MyExtractor
и использую его:
let myExtractor = new MyExtractor();
let processed = myExtractor.process('blah');
Вопрос 1. Почему это не приводит к ошибке времени компиляции? Основываясь на определении интерфейса Extractor
, я ожидаю, что компилятор не позволит мне вызывать myExtractor.process()
ни с чем, кроме экземпляра MyClass
, или, по крайней мере, с чем-то структурно совместимым.
Вопрос 2. Как обеспечить желаемое поведение? Мне просто нужно утверждать, что параметр candidate
для MyExtractor.process()
имеет тип MyClass
?
Я подозреваю, что это как-то связано со структурной системой типизации TypeScript, но после прочтения некоторые связанные вопросы и Часто задаваемые вопросы, я до сих пор не уверен, как это конкретно применимо здесь.
Моя версия Typescript 2.1.4.