#typescript
#typescript
Вопрос:
У меня есть модуль, который определяет несколько классов, которые принимают параметры типа ( <T>
) и реализуют интерфейс ( my_interface
).
// [my_module.ts]
import {my_interface} from ".typings.d.ts"
export class Class_A <T> implements my_interface {
blah blah blah;
}
export class Class_B <T> implements my_interface {
blah blah blah;
}
и у меня есть .d.ts
файл, который определяет интерфейсы для экземпляров класса:
// [typings.d.ts]
export interface my_interface <T> {
blah:blah;
}
Я хочу добавить интерфейс, который описывает модуль в целом, но в следующем появляется сообщение «TS2304: не удается найти имя ‘T'». ошибка:
// [typings.d.ts]
export interface MY_MODULE {
Class_A: my_interface<T>;
Class_B: my_interface<T>;
}
и следующее вызывает ошибку «TS2314: для универсального типа ‘my_interface’ требуется 1 аргумент (ы) типа».:
// [typings.d.ts]
export interface MY_MODULE {
Class_A: my_interface;
Class_B: my_interface;
}
Есть ли способ создать интерфейс ( MY_MODULE
) для описания объекта, который импортируется при импорте скомпилированного JS-кода через:
var my_module:MY_MODULE = require("my_module")
Комментарии:
1. Не должно быть необходимости определять тип модуля, компилятор должен вывести все о самом модуле. Если вам позже понадобится, вы можете сделать:
typeof my_module
.2. Не тогда, когда модуль импортируется из скомпилированных файлов JS, т. Е. Когда Модуль устанавливается через
npm
илиbower
. Вот почему я пишу.d.ts
файл.3. Ну, вы пробовали ссылаться на файл определения:
/// <reference path="path/to/defnitions.d.ts" />
?4. Да, именно тогда появляются сообщения об ошибках, приведенные выше, т. Е. Когда компилятор сценария типа обнаруживает объявление
MY_MODULE
интерфейса.5. Я не совсем уверен, что вы пытаетесь сделать, но вы не должны создавать интерфейс для модуля.
Ответ №1:
Я должен задаться вопросом, правильно ли вы используете здесь дженерики. В любом случае, прошлое наименьшего сопротивления, чтобы сделать то, что вы хотели бы сделать, это: сделать MY_MODULE
generic.
export interface MY_MODULE<T> {
Class_A: my_interface<T>;
Class_B: my_interface<T>;
}
После этого параметр будет разрешен правильно. Затем при импорте вы должны ввести его как
var my_module:MY_MODULE<type-here> = require("my_module")
если вам все равно, что в него вводится, продолжайте и делайте
var my_module:MY_MODULE<any> = require("my_module")
Это имеет некоторые последствия. Это означает, что type_A
и type_B
оба являются общими для одного и того же типа. Так ли это задумано? Если нет, то вместо того, чтобы использовать :my_interface<T>
в аннотации вашего типа, вы должны заполнить интересующий вас тип, над которым работают type_A и type_B. Если вам все равно, вы можете снова использовать any
.
Хотите ли вы запретить предоставление информации о типе до тех пор, пока она не будет использована? Возможно, типы A и B представляют собой какие-то коллекции, и вы хотели бы, чтобы они переносили тип, на котором они инициализируются, на последующие вызовы функций. Вы также можете добиться этого, но вам нужно будет использовать такую функцию, как:
interface ExampleModule {
Class_A: <T> (param: T) => my_interface<T>
}
или конструктор, такой как:
interface ExampleModule {
Class_A: { new<T>(): my_interface<T> };
}
а затем используйте созданный объект.
Комментарии:
1. Интерфейс конструктора — это именно то, что я искал. Спасибо!