interfaceпредназначен для случаев, когда вы просто хотите описать форму объекта. Для интерфейсов никогда не существует генерации кода - они всего лишь артефакт в системе типов. Вы не увидите разницы в генерации кода для класса в зависимости от того, есть ли у него implementsпредложение.
declare classпредназначен для случаев, когда вы хотите описать существующий класс (обычно класс TypeScript, но не всегда), который будет присутствовать извне (например, у вас есть два файла .ts, которые компилируются в два файла .js, и оба включаются с помощью scriptтегов на веб-странице). Если вы наследуете от classusing extends(независимо от того, был ли базовый тип a declare classили обычным class), компилятор сгенерирует весь код для подключения цепочки прототипов и конструкторов пересылки, а что нет.
Если вы попытаетесь наследовать от, declare classкоторый должен был быть интерфейсом, у вас будет ошибка времени выполнения, потому что этот сгенерированный код будет ссылаться на объект без проявления времени выполнения.
И наоборот, если вы просто implementинтерфейс, который должен был быть declare class, вам придется заново реализовать все члены самостоятельно и не будете использовать преимущества какого-либо повторного использования кода из потенциального базового класса, а функции которые проверяют цепочку прототипов во время выполнения, отклонят ваш объект как не являющийся экземпляром базового класса.
Для того, чтобы получить действительно всезнайка, если у вас есть C ++ фона, вы можете примерно думать , interfaceкак typedefи в declare classкачестве externдекларации конструктора , который строго отсутствует определение в этой компиляции единицы.
С точки зрения чистого потребления (написание императивного кода, а не добавление новых типов) единственная разница между interfaceи declare classзаключается в том, что вы не можете создавать newинтерфейс. Тем не менее, если вы собираетесь extend/ implementодин из этих типов в новом class, Вы абсолютно должны быть выбраны правильно между interfaceи declare class. Только один из них будет работать.
Два правила, которые вам пригодятся:
- Согласуется ли имя типа с функцией-конструктором (чем-то вызываемым
new), которая действительно присутствует во время выполнения (например, Dateесть, но JQueryStaticнет)? Если нет , то точно хочешьinterface
- Имею ли я дело со скомпилированным классом из другого файла TypeScript или с чем-то достаточно похожим? Если да , используйте
declare class