为原型函数添加类型

时间:2019-04-17 20:19:37

标签: node.js typescript

我在Node模块中有一个JavaScript function,如下所示(简化):

index.js

var BadRequestError = require('./error')

Guard.prototype = {

  /**
   *
   * @param {String} property
   * @return {_middleware}
   */
  check: function (property) {
    const _middleware = function _middleware (req, res, next) {
      const ok = property === 'ping'
      next(!ok ? new BadRequestError('doing_it_wrong', { message: `you're doing it wrong`}) : null)
    }

    return _middleware
  }
}

module.exports = function (options) {
  return new Guard(options)
}

error.js

module.exports = function BadRequestError (code, error) {
  Error.captureStackTrace(this, this.constructor)

  this.name = this.constructor.name
  this.message = error.message

  this.code = code
  this.status = 400
  this.inner = error
}

util.inherits(module.exports, Error)

用法如下:

test.js

var guard = require('../index')({
  someProperty: 'test',
})
var req = {}
guard.check('ping')(req, res, function (err) {
  assert.deepStrictEqual(null, err)
})

我尝试使用几种方法为其创建TypeScript类型,但似乎没有一种方法起作用

index.d.ts

export declare interface IGuardOptions {
    property: string
}

通过class声明导出:

export declare class Guard  {
    constructor(options: IGuardOptions)
    check(required: string | Array<string>): any
}

通过interface声明导出:

export declare interface Guard {
    check(property: string): any
}
export declare type GuardConstructor = new(options: IGuardOptions) => Guard

1 个答案:

答案 0 :(得分:1)

由于您没有编写任何Typescript代码,而只是声明,因此尚不清楚“不起作用”的含义,因此我假设test.js应该是test.ts来回答您的问题。

您将要在原始Javascript源旁边创建一个类型声明(就像您已经做过的一样),但是您需要确保该结构与原始模块等效。您的Typescript声明表明存在多个导出,而Javascript实现仅具有单个导出。

error.d.ts

declare class BadRequestError extends Error {
    code: string;
    status: number;
    inner: Error;

    constructor(code: string, error: Error);
}

export = BadRequestError;

index.d.ts

import {Handler} from 'express';

declare interface GuardOptions {
    someProperty: string;
}

declare class Guard {
    constructor(options: GuardOptions);

    check(property: string): Handler;
}

declare function guardFactory(options: GuardOptions): Guard;

export = guardFactory;

test.ts

import {Request, Response} from 'express';

import guardFactory = require('./index');

const guard = guardFactory({
    someProperty: 'test',
});

const middleware = guard.check('ping');

const req = {} as Request;
const res = {} as Response;
const next = function (err) {
    assert.deepStrictEqual(null, err);
};

middleware(req, res, next);