【问题标题】:How can I augment a typescript interface using a type exported from another .d.ts file?如何使用从另一个 .d.ts 文件导出的类型来扩充打字稿界面?
【发布时间】:2016-04-16 16:47:06
【问题描述】:

这是我的用例:

我们的 Promise 库有一个非常轻量级的抽象,因为我们现在出于各种原因对其进行了多次更改,并且我们不希望在整个应用程序中更改代码。

我想向 express.Request 实例添加一个中间件,我可以通过扩展接口轻松做到这一点,如下所示:

declare namespace Express {
    export interface Request {
        loginP(user: any): void;
    }
}

把它单独放在一个 .d.ts 文件中,一切都很好,太棒了。

但是。这是我的麻烦;在我的抽象中,我重新导出了我们正在使用的 Promise 库的接口,以便我们可以在整个应用程序中使用它并进行良好的类型检查,而不需要到处都知道它来自哪里:

import * as bluebird from 'bluebird';

export {bluebird as PType};

这很好用;但是,仅当 .d.ts 文件不导出或导入任何内容时,扩充接口才有效,因此当我尝试让 loginP 返回 PType<void>,它实际返回的类型时,扩充突然停止工作:

import {PType} from '../lib/Promise';

declare namespace Express {
    export interface Request {
        loginP(user: any): PType<void>;
    }
}

(使用上面的代码,在界面的任何地方都找不到成员loginP)。如果我删除 import {PType} 行,一切正常——除了我无法返回我需要的类型。

有什么想法吗?我正在使用带有 tsconfig 文件的 typescript 1.8.9,使用 tsc -p . 构建

【问题讨论】:

  • 这是什么../lib/Promise 文件?是.ts.d.ts 还是别的什么?如果您使用/// &lt;reference path="../lib/Promise" /&gt; 而不是导入会发生什么?
  • 这是一个 .ts 文件,添加该引用不会引起任何注意

标签: typescript typescript1.8


【解决方案1】:

我认为您的问题是您正在尝试执行模块合并(只要您的代码中有导出/导入语句 - 模块变为外部)。即使它不直接支持 - 你仍然可以这样做。

下面我发布了直接从typescript handbook 复制的代码作为如何执行此操作的示例:

// observable.ts stays the same
// map.ts
import { Observable } from "./observable";
declare module "./observable" {
    interface Observable<T> {
        map<U>(f: (x: T) => U): Observable<U>;
    }
}
Observable.prototype.map = function (f) {
    // ... another exercise for the reader
}


// consumer.ts
import { Observable } from "./observable";
import "./map";

let o: Observable<number>;
o.map(x => x.toFixed());

希望这会有所帮助。

【讨论】:

  • 所以打字稿基本上不允许使用来自另一个模块的类型来扩充接口?不幸的是,我认为解决方法对我们不起作用。不过,它可能会给我一个可以尝试的不同解决方法的想法:-/
  • 我知道的唯一方法是使用我提到的技术。是的 - 它不像合并接口/命名空间那么容易。
  • 不是我希望的答案,但这不是你的错 =] 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2017-02-04
  • 2020-10-14
  • 2020-09-08
  • 2022-06-23
  • 2021-09-26
  • 1970-01-01
相关资源
最近更新 更多