2

我正在尝试使用 TypeScript 和 Express。我已经从 Typings 加载了类型声明,它们看起来像这样:

// Generated by typings
// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/express/express.d.ts
declare module "express" {
    import * as serveStatic from "serve-static";
    import * as core from "express-serve-static-core";

    /**
     * Creates an Express application. The express() function is a top-level function exported by the express module.
     */
    function e(): core.Express;

    namespace e {

        /**
         * This is the only built-in middleware function in Express. It serves static files and is based on serve-static.
         */
        var static: typeof serveStatic;

        export function Router(options?: any): core.Router;

        interface Application extends core.Application { }
        interface CookieOptions extends core.CookieOptions { }
        interface Errback extends core.Errback { }
        interface ErrorRequestHandler extends core.ErrorRequestHandler { }
        interface Express extends core.Express { }
        interface Handler extends core.Handler { }
        interface IRoute extends core.IRoute { }
        interface IRouter<T> extends core.IRouter<T> { }
        interface IRouterMatcher<T> extends core.IRouterMatcher<T> { }
        interface MediaType extends core.MediaType { }
        interface NextFunction extends core.NextFunction { }
        interface Request extends core.Request { }
        interface RequestHandler extends core.RequestHandler { }
        interface RequestParamHandler extends core.RequestParamHandler { }
        export interface Response extends core.Response { }
        interface Router extends core.Router { }
        interface Send extends core.Send { }
    }

    export = e;
}

现在我正在尝试扩展所有 Response 对象的原型,如下所示:

const express = require('express');
express.response.sendWrapped = function(obj: Object, meta?: Object) {
    return this.json({
        data: obj
    });
};

现在我只需要将扩展​​名放入打字中。我很想将此方法扩展到现有定义中,就像我在原型中扩展它的方式一样,但我不确定如何去做。

由于这是库类型定义的个人扩展,我认为这属于主类型集,我应该为了自己的目的手动修改它们。以我自己的方式扩展它们的最佳方法是什么?我可以在不覆盖依赖于响应的所有其他部分的情况下做到这一点吗?

4

2 回答 2

2

使用 TypeScript 2.0 或它的预发布版本 ( typescript@next),您可以使用模块扩充语法来扩充 的定义express以包含您的新response定义:

import express = require('express');

declare module "express" {
    namespace response {
        function sendWrapped(obj: any, meta?: any): void;
    }
}

express.response.sendWrapped = function(obj: Object, meta?: Object) {
    return this.json({
        data: obj
    });
};

于 2016-05-31T22:47:44.367 回答
-1

一些东西:

(1)response您包含的声明中没有,有一个Response,所以它应该是:express.Response.sendWrapped

(2)您没有为所有Responses扩展原型,您将sendWrapped函数添加到类本身(我假设这Response是一个类)。
如果要添加到原型中,它应该如下所示:

express.Response.prototype.sendWrapped = function(obj: Object, meta?: Object) {
    return this.json({
        data: obj
    });
};

(3) 您可以像这样添加到现有类型:

namespace express {
    interface Response {
        sendWrapped(obj: Object, meta?: Object): any;
    }
}

更多关于声明合并


编辑

如果它在一个d.ts文件中,那么你需要它是:

declare namespace express {
    ...
}

我不知道为什么它不允许你合并声明,而且我没有这个设置来自己测试它,但我有另一个解决方案,在我看来,它更好。

只需在其中扩展express.Response添加您需要的内容,例如:

class MyResponse extends express.Response {
    constructor() {
        super();
    }

    sendWrapped(obj: Object, meta?: Object): express.Response {
        return this.json({
            data: obj
        });
    }
}

这更好,因为您不会因为 express api 的变化而受到影响,而且更重要的是,这就是面向对象的用途。

于 2016-05-29T07:02:46.647 回答