在定义文件 (*d.ts) 中导入类 [英] Import class in definition file (*d.ts)

查看:85
本文介绍了在定义文件 (*d.ts) 中导入类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想扩展 Express Session 类型以允许在会话存储中使用我的自定义数据.我有一个对象 req.session.user,它是我的类 User 的一个实例:

I want to extend Express Session typings to allow use my custom data in session storage. I have an object req.session.user which is an instance of my class 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 文件以将定义与现有的快速会话类型合并:

So i created my own.d.ts file to merge definition with existing express session typings:

import { User } from "./models/user";

declare module Express {
    export interface Session {
        user: User;
    }
}

但它根本不起作用 - VS Code 和 tsc 看不到它.所以我用简单的类型创建了测试定义:

But it's not working at all - VS Code and tsc don't see it. So I created test definition with simple type:

declare module Express {
    export interface Session {
        test: string;
    }
}

并且测试字段工作正常,因此导入导致问题.

And the test field is working ok, so the import cause problem.

我也尝试添加 ///<reference path='models/user.ts'/> 而不是 import 但 tsc 没有看到 User 类 - 我该如何使用*d.ts 文件中我自己的类?

I also tried to add /// <reference path='models/user.ts'/> instead import but the tsc didn't see the User class - how can I use my own class in *d.ts file?

我将 tsc 设置为在编译时生成定义文件,现在我有了 user.d.ts:

I set tsc to generate definition files on compile and now I have my user.d.ts:

export declare class User {
    login: string;
    hashedPassword: string;
    constructor();
    constructor(login: string, password: string);
}

以及用于扩展 Express Sesion 的自己的输入文件:

And the own typing file for extending Express Sesion:

import { User } from "./models/user";
declare module Express {
    export interface Session {
        user: User;
        uuid: string;
    }
}

但是当 import 语句在上面时仍然不起作用.有什么想法吗?

But still not working when import statement on top. Any ideas?

推荐答案

经过两年的 TypeScript 开发,我终于设法解决了这个问题.

After two years of TypeScript development, I've finally managed to solve this problem.

基本上,TypeScript 有两种模块类型声明:本地"(普通模块)和环境(全局).第二种允许编写与现有模块声明合并的全局模块声明.这些文件之间有什么区别?

Basically, TypeScript has two kind of module types declaration: "local" (normal modules) and ambient (global). The second kind allows to write global modules declaration that are merged with existing modules declaration. What are the differences between this files?

d.ts 文件仅在没有任何导入时才被视为环境模块声明.如果您提供了一个导入行,它现在被视为一个普通的模块文件,而不是全局文件,因此增加模块定义不起作用.

d.ts files are treated as an ambient module declarations only if they don't have any imports. If you provide an import line, it's now treated as a normal module file, not the global one, so augmenting modules definitions doesn't work.

这就是我们在这里讨论的所有解决方案都不起作用的原因.但幸运的是,从 TS 2.9 开始,我们可以使用 import() 语法将类型导入到全局模块声明中:

So that's why all the solutions we discussed here don't work. But fortunately, since TS 2.9 we are able to import types into global modules declaration using import() syntax:

declare namespace Express {
  interface Request {
    user: import("./user").User;
  }
}

所以 import("./user").User; 这行很神奇,现在一切正常:)

So the line import("./user").User; does the magic and now everything works :)

这篇关于在定义文件 (*d.ts) 中导入类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆