#typescript
#typescript
Вопрос:
Допустим, у меня есть файловое дерево с кодом и ресурсами TypeScript, которые я обслуживаю с некоторого произвольного URL (например, между CDN и местоположением отладки) — я хочу иметь возможность импортировать корень этого модуля и разрешить правильному импорту остальной части дерева, когда это необходимо(т. е. Без необходимости указывать путь загрузки более одного раза).
В JavaScript я, вероятно, мог бы сделать что-то вроде этого:
export class MyModule {
private dependentModulePromise;
constructor(rootpath) {
this.dependentModulePromise = import(rootpath '/dependentModule');
}
}
Однако, если бы я должен был сделать это в TypeScript, я бы хотел, чтобы он был максимально безопасным для типов. Очевидно, что мне нужно было бы использовать утверждение типа здесь для исходного импорта динамической строки, но как я могу безопасно сообщить TypeScript о загружаемом типе, не сталкиваясь с конфликтами имен или синхронным импортом модуля (который, в чем-то вроде Webpack, делает его частью пакета)?
Я попробовал это расширение:
import * as DependentModule from '/dependentModule';
export class MyModule {
private dependentModulePromise: Promise<DependentModule>;
constructor(rootpath) {
this.dependentModulePromise = import(rootpath '/dependentModule') as Promise<DependentModule>;
}
}
но в итоге я получаю сообщение об ошибке, сообщающее мне, что пространство DependentModule
имен не может использоваться в качестве типа.
Комментарии:
1. Проблема заключается в
import *
. Когда вы импортируете все из файла и присваиваете ему имя likeDependentModule
, typescript видит это как пространство имен, а отдельные элементы экспортируются как значения в этом пространстве имен. Есть ли/dependentModule
экспорт по умолчанию?2. @LindaPaiste Обязательно ли он должен быть? Если это произойдет, я мог бы заставить это работать, хотя я бы предпочел иметь возможность импортировать произвольный модуль, если бы мог.
3. Честно говоря, я не знаю, действительно ли это решит вашу проблему. Я просто знаю, что import * является источником текущей ошибки.
Ответ №1:
Вот что-то очень близкое: если /dependentModule
имеет экспорт по умолчанию, вместо того, чтобы пытаться экспортировать пространство имен, тогда он работает нормально.
// Here, dependentModule exports a class
import { default as DependentModule_TYPE_ONLY } from '/dependentModule';
export class MyModule {
private dependentModulePromise: Promise<new () => DependentModule_TYPE_ONLY>;
constructor(rootpath) {
this.dependentModulePromise = import(rootpath '/dependentModule') as Promise<new () => DependentModule>;
}
public async doStuffWithDependentModule() {
const DependentModule = await this.dependentModulePromise;
const m = new DependentModule();
// now do typesafe stuff with m
}
}
Очевидно, что лучший маршрут — это если этот экспорт по умолчанию реализует некоторый интерфейс или форму типа, найденную в другом месте, чтобы обещание можно было использовать для этого, а не как экземпляр класса (т. Е. Если DependentModule
implements IInterfaceOfInterest
, то import
обещание имеет тип Promise<new () => IInterfaceOfInterest>
).