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