Импортировать класс в файл определения (*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 файл декларации.