Что предпочтительнее в TypeScript при создании файлов декларации источника .d.ts и почему?
declare class Example {
public Method(): void;
}
или
interface Example {
Method(): void;
}
Различия, которые я могу сказать, заключаются в том, что интерфейсы не могут иметь статических методов, поэтому вы должны использовать для этого класс. Оба не производят никакого JS-вывода, так что, возможно, это не имеет значения?
javascript
typescript
Крис
источник
источник
Ответы:
interface
предназначен для случаев, когда вы просто хотите описать форму объекта. Для интерфейсов никогда не существует генерации кода - они всего лишь артефакт в системе типов. Вы не увидите разницы в генерации кода для класса в зависимости от того, есть ли у негоimplements
предложение.declare class
предназначен для случаев, когда вы хотите описать существующий класс (обычно класс TypeScript, но не всегда), который будет присутствовать извне (например, у вас есть два файла .ts, которые компилируются в два файла .js, и оба включаются с помощьюscript
тегов на веб-странице). Если вы наследуете отclass
usingextends
(независимо от того, был ли базовый тип adeclare 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
declare class
источник
new
оператор для типа интерфейса. Однако интерфейсы могут иметь конструктивные сигнатуры, что означает, что вы можете вызыватьnew
оператор для значения типа интерфейса. Это сильно отличается от тогоclass
, как работает, когда подпись конструкции находится в самом имени типа, а не в выражении этого типа.Вы можете реализовать интерфейс:
В то время как
declare class
синтаксис действительно предназначен для использования для добавления определений типов для внешнего кода, который не написан на TypeScript, поэтому реализация находится «в другом месте».источник
С точки зрения непрофессионала,
declare
используется в.ts
/d.ts
files, чтобы сообщить компилятору, что мы должны ожидать, что ключевое слово, которое мы будемdeclaring
существовать в этой среде, даже если оно не определено в текущем файле. Это затем позволит нам обеспечить безопасность типов при использовании объявленного объекта, поскольку компилятор Typescript теперь знает, что какой-то другой компонент может предоставить эту переменную.источник
Разница между
declare
иinterface
в TS:заявляет:
В приведенном выше коде
declare
компилятор TS знает, что где-тоExample
объявлен класс . Это не значит, что класс включен волшебным образом. Вы как программист несете ответственность за доступность класса при его объявлении (сdeclare
ключевым словом).интерфейс:
An
interface
- это виртуальная конструкция, которая существует только в машинописном тексте. Компилятор машинописного текста использует его исключительно для проверки типов. Когда код компилируется в javascript, вся эта конструкция будет удалена. Компилятор машинописного текста использует интерфейсы для проверки правильности структуры объектов.Например, когда у нас есть следующий интерфейс:
Объекты, которые мы определяем с этим типом интерфейса, должны точно соответствовать интерфейсу:
источник