Импортировать класс в файл определения (*d.ts)
Я хочу расширить Express Session typings, чтобы разрешить использовать мои пользовательские данные в хранилище сеансов. У меня есть объект req.session.user
который является экземпляром моего класса User
:
export class User {
public login: string;
public hashedPassword: string;
constructor(login?: string, password?: string) {
this.login = login || "" ;
this.hashedPassword = password ? UserHelper.hashPassword(password) : "";
}
}
поэтому я создал свой own.d.ts
файл для слияния определения с существующими типами экспресс-сеанса:
import { User } from "./models/user";
declare module Express {
export interface Session {
user: User;
}
}
но он не работает вообще-VS Code и tsc не видят его. Поэтому я создал определение теста с простым типом:
declare module Express {
export interface Session {
test: string;
}
}
и поле теста работает нормально, поэтому импорт вызывать проблемы.
Я также попытался добавить /// <reference path='models/user.ts'/>
вместо импорта, но tsc не видел класс пользователя - как я могу использовать свой собственный класс В *d.TS файл?
EDIT: Я установил tsc для создания файлов определений при компиляции, и теперь у меня есть пользователь.д.ТС:
export declare class User {
login: string;
hashedPassword: string;
constructor();
constructor(login: string, password: string);
}
и собственный файл ввода для расширения Express Sesion:
import { User } from "./models/user";
declare module Express {
export interface Session {
user: User;
uuid: string;
}
}
но все еще не работает, когда оператор импорта сверху. Есть идеи?
2 ответов
после двух лет разработки TypeScript мне наконец удалось решить эту проблему.
в основном, TypeScript имеет два вида объявления типов модулей:" локальный " (обычные модули) и окружающий (глобальный). Второй вид позволяет писать глобальные объявления модулей, которые объединяются с существующими объявлениями модулей. В чем разница между этими файлами?
d.ts
файлы рассматриваются как объявления окружающего модуля, только если они не имеют импорта. Если вы предоставляете строку импорта, теперь она рассматривается как обычный файл модуля, а не глобальный, поэтому увеличение определений модулей не работает.
так вот почему все решения, которые мы обсуждали здесь не работает. Но, к счастью, с TS 2.9 мы можем импортировать типы в глобальную декларацию модулей, используя import()
синтаксис:
declare namespace Express {
interface Request {
user: import("./user").User;
}
}
вот эта строка import("./user").User;
сделать волшебство и теперь все работает :)
Я думаю, что проблема, с которой вы столкнулись, больше о увеличение деклараций модулей затем курс машинописи.
экспорт в порядке, как вы заметите, если вы попытаетесь скомпилировать это:
// app.ts
import { User } from '../models/user'
let theUser = new User('theLogin', 'thePassword')
похоже, вы пытаетесь увеличить объявление модуля Express
, и вы действительно близки. Это должно сделать трюк:
// index.d.ts
import { User } from "./models/user";
declare module 'express' {
interface Session {
user: User;
uuid: string;
}
}
однако правильность этого кода зависит, конечно, от первоначальной реализации express файл декларации.