Интерфейс для объекта, членами которого являются классы

#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. Интерфейс конструктора — это именно то, что я искал. Спасибо!