#typescript #class #module #declaration #.d.ts
Вопрос:
Я пытаюсь преобразовать проект javascript в машинописный текст. Этот проект основан на ванильной библиотеке/модуле javscript, в которой отсутствуют официальные объявления типов, что означает, что я должен написать свой собственный.
В настоящее время мой проект импортирует библиотеку следующим образом:
const lib = require('library-name')
Все модули/классы, содержащиеся в этом библиотечном модуле, импортируются следующим образом:
const module = lib.module
Компилятор не сообщает об ошибках при импорте, и их нет, когда я пишу свой файл .d.ts в этой форме (для необъектных модулей).:
declare module 'library-name' {
...
declare module 'module1' {
function functionName: functionType;
}
...
}
Однако некоторые из этих модулей также являются КЛАССАМИ ОБЪЕКТОВ — другими словами, их экземпляры можно создавать с помощью » нового класса ()». Я пытаюсь объявить их следующим образом:
declare module 'library-name' {
declare module class_module{
class class_module {
function1(parameter: type): functionType;
function2(): void;
}
export = class_module;
}
}
Когда я пытаюсь ввести переменную или константу в качестве типа class_module, т. Е.
let var: class_module = something;
Я получаю сообщение об ошибке «‘class_module’ относится к значению, но используется здесь в качестве типа». Я трижды проверил, чтобы убедиться, что я импортирую его в файл .ts и объявляю его в файле .d.ts точно так же, как и все остальные модули.
Чтобы сделать вещи более запутанными, есть один класс, с которым этого не происходит — компилятор не жалуется, когда я использую его для ввода константы или переменной. Однако я не могу использовать ни одну из функций этого класса, так как всегда получаю сообщение об ошибке:
Это выражение не может быть вызвано. Тип «Имя объекта typeof» не имеет сигнатур вызовов.
Я не знаю, актуально ли это, но все другие классы, которые выдают ошибку об использовании значений в качестве типов, используют «модуль экспорта», в то время как тот, который не выдает эту ошибку, использует более неясный и чужой (для меня) синтаксис, начиная файл с
(function(exports) {
and ending with
exports.ClassName = ClassName; })(typeof exports !== 'undefined' ? exports : this);
Имеет ли значение способ экспорта каждого модуля?
Я перепробовал все способы переключения, импорта и объявления модулей по-разному с помощью:
- используя «импорт {модуль1, модуль2, … модуль n} из»модуля»»
- объявление модулей в качестве пространств имен, интерфейсов, классов (напрямую), что у вас есть в .d.ts
- … и различные другие снимки в темноте. Кажется, ничто не имеет большого значения или какой-либо разницы.
Ответ №1:
Вы можете определить class_module
как класс, а затем расширить его с помощью пространства имен:
declare module 'library-name' {
declare namespace class_module {
export = class_module
}
declare class class_module {
function1(parameter: type): functionType
function2(): void
}
}
Для использования модуля:
import {class_module} from 'library-name'
// or
import lib from 'library-name'
const {class_module} = lib
type class_module = lib.class_module
const foo: class_module = new class_module()
См. Также (из руководства по машинописи):
Комментарии:
1. Это сработало. Ну, отчасти так оно и было. Объявление пространства имен ничего не дало. «импорт {class_module} из» имени библиотеки » ничего не сделал. Однако третья часть этого — даже без этих первых двух («импорт библиотеки из «имени библиотеки»… введите class_module = lib.class_module») сделал свое дело. Я предполагаю, что это сработало, потому что он явно объявил модуль как тип?
2. Пока это работает, это похоже на «халтурное» решение. Будет ли это в целом считаться хорошей практикой?
3. Мне пришлось сделать еще несколько хитрых вещей, чтобы eslint перестал жаловаться на другие вещи, связанные с машинописью, в моем коде.