#javascript #typescript
#javascript #typescript
Вопрос:
У меня есть интерфейс TypeScript, подобный этому:
export interface Foo {
bar: string
}
Это приведет к компиляции в пустой .js
файл.
Поэтому при использовании интерфейса TypeScript в узловом модуле ES6 я получаю эту ошибку:
TypeError: Class extends value undefined is not a function or null
Обходным путем будет создание класса
export class BaseFoo {
bar: string
}
Теперь я могу использовать BaseFoo
из ES6 без получения вышеупомянутой ошибки.
Таким образом, невозможно просто иметь интерфейсы в TypeScript с взаимодействием ES6 или есть более элегантный способ, чем наличие Base*
классов (которые в конечном итоге не являются базовыми классами) здесь?
Обновить: Я понимаю различные концепции, лежащие в основе интерфейсов и базовых классов, но мои вопросы касаются наилучшей практики, как создать библиотеку в TypeScript, которая использует интерфейсы, и как построить ее таким образом, чтобы обычный ES6 (у которого нет интерфейсов) также мог использовать эту библиотеку.
Комментарии:
1. Что вы имеете в виду, используя интерфейс? Typescript не позволит вам использовать интерфейс, поскольку интерфейсы — это просто типы, а типы стираются. Вы используете интерфейсы для проверки типа значений в typescript, во время выполнения они бесполезны.
2. Класс реализует интерфейс, он не может его расширять.
3. @TitianCernicova-Dragomir Я обновил вопрос.
4. @AlexanderZeitler потребителю js просто наплевать на интерфейсы, код все еще можно использовать, где интерфейс должен быть передан, они могут просто передать объектный литерал, который удовлетворяет интерфейсу (конечно, без проверки) или классу, который они создают. Вы также можете создавать классы для интерфейсов, но я не думаю, что для этого есть причина, если у вас нет другого требования..
5. Если я не создаю
class
в TS, я получаю вышеупомянутую ошибку. Я хочу убедиться, что сигнатура свойстваinterface
из TS также будет доступна. Итак, мое текущее понимание таково, что я могу использоватьinterface
в TS как есть, но для взаимодействия с JS мне нужно создать,class
которое можноextend
редактировать в обычном JS, не приводя к ошибке выше. Чтобы действовать болееinterface
похоже, я также мог бы добавитьNotImplementedError
s в класс, который яextend
создаю.
Ответ №1:
Я думаю, вы неправильно понимаете, как правильно использовать интерфейс. Интерфейсы не являются «базовыми» объектами, они просто определяют, как должен выглядеть объект.
В typescript интерфейс часто используется как тип для объекта, но в целом его можно использовать и для определения того, как должен «выглядеть» класс.
Например:
interface Foo {
bar: string;
baz: number;
bang(): void;
}
В этом случае любой объект / класс, который implements
Foo
должен будет иметь эти три вещи.
IE:
class FooImplemented implements Foo {
bar = 'Hello World';
baz = 42;
bang() {
print(this.bar);
}
}
Если я не определю bar, baz и / или bang; typescript выдаст ошибку во время компиляции, что я неправильно реализую Foo
интерфейс в FooImplemented
классе.
Подводя итог, интерфейс сообщает компилятору, как что-то должно выглядеть. И интерфейс может расширять другой интерфейс. Однако класс не может расширить интерфейс, но он может его реализовать. (Или несколькими)
Ознакомьтесь с документами по интерфейсам на веб-сайте typescripts.
Комментарии:
1. Я понимаю различные концепции, лежащие в основе интерфейсов и базовых классов, но мои вопросы касались наилучшей практики, как создать библиотеку в TypeScript, которая использует интерфейсы, и как построить ее таким образом, чтобы обычный ES6 (у которого нет интерфейсов) также мог использовать эту библиотеку.
2. @AlexanderZeitler ошибка предполагает, что вы используете
extends
вместоimplements
?3. @Evert
implements
не существует в обычном JS, вот почему я используюextends
, и именно по этой причине я ищу обходной путь / наилучшую практику для решения всей этой проблемы.4. @AlexanderZeitler ах, теперь я понимаю. Тогда эквивалент, не являющийся typescript, на самом деле не реализует / расширяет все это. В этом не было бы смысла, потому что все это происходило бы во время выполнения, а typescript вообще ничего не применяет во время выполнения.
Ответ №2:
Возможно, вы захотите использовать эту аннотацию @implements jsdoc:
/** @implements {Print} */
class TextBook {
print() {
// TODO
}
}