【问题标题】:Adding to existing library typescript types with a new definition file使用新定义文件添加到现有库 typescript 类型
【发布时间】:2018-12-20 05:02:53
【问题描述】:

我正在使用这个库 https://github.com/chentsulin/koa-bearer-token,它为 koa 库请求对象添加了一个额外的属性,例如 ctx.request.token。因此,如果我直接使用 koa 类型,我会收到一个错误,告诉我 token 属性在 ctx.request.token 上不存在。

我目前的解决方案

我创建了一个名为 koa-bearer-token.d.ts 的类型定义文件,其中包含库的类型和扩展 koa 上下文/请求类型的导出:

declare module 'koa-bearer-token' {
    import {Context, Request, Middleware} from 'koa';

    interface Options {
        queryKey?: string;
        bodyKey?: string;
        headerKey?: string;
        reqKey?: string;
    }

    interface RequestWithToken extends Request {
        token?: string
    }

    interface ContextWithToken extends Context {
        request: RequestWithToken
    }

    export default function bearerToken(options?: Options): Middleware;
    export {RequestWithToken, ContextWithToken};
}

然后我在其他文件中使用它:

import {ContextWithToken} from 'koa-bearer-token';
const someFunction = (ctx: ContextWithToken) => {
    const token = ctx.request.token; // <-- No longer errors
};

我为什么要问这个问题

现在可行,但我担心这不是最好的方法,因为如果我将来需要添加更多属性,它将无法正常工作,理想情况下,我只想创建一个 koa.d.ts 文件添加到库类型然后我可以继续使用 import {Context} from 'koa'; 而不是 import {ContextWithToken} from 'koa-bearer-token'; 但是当我创建 koa.d.ts 它会覆盖所有库类型而不是在它们之上添加。

这是我的 tsconfig.json 以防万一

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": [
        "node_modules/*",
        "src/@types/*"
      ]
    }
  },
  "include": [
    "src/**/*"
  ]
}

【问题讨论】:

    标签: typescript types koa


    【解决方案1】:

    您可以尝试使用模块扩充。您不必声明新模块。 Typescript 将合并这两个模块,您应该拥有旧的 koa 类型和新的类型。

    import * as koa from "koa"
    declare module 'koa'{
        interface Request {
            token: string;
        }
    }
    
    declare const c: koa.Request;
    c.token = 'tre';
    

    棘手的是它必须放在 koa 导入之后。因此,我建议将此新更改设置在一个单独的文件中,以便在任何地方轻松应用您的更改。

    import * as koa from "koa";
    import '<path to>koachanges';
    

    希望有帮助

    关于你说的,我会说这是可能的。

    更改您的 tsconfig 以添加全局 d.ts 文件。

     ...
     "typeRoots": ["./node_modules/@types", "./typings"]
     ...
    

    在项目根目录下的这个新的类型文件夹中添加一个 index.d.ts 文件并将其放入。

    import * as Koa from 'koa';
    declare module 'koa'{
        interface Request {
            token: string;
        }
    }
    

    重要的是添加第一个导入,然后将 koa 类型导入到您的全局文件中,然后您可以覆盖它们。

    【讨论】:

    • 谢谢@kimy82!所以没有办法在koa.d.ts 文件中全局增加 koa 类型?我不能这样做似乎很奇怪,也就是说,即使我想为 koa-bearer-token 添加类型到 distinctlyTyped 中,子库作者也没有办法添加属性。所以每次有人安装像 koa-bearer-token 这样的子库时,子库添加的属性总是会输入错误?
    • 感谢您提供更新的答案,这很有效!我最初将我的文件命名为 koa.d.ts,它仍然覆盖了所有 koa 类型,但将其命名为 koa-extensions.d.ts 并根据答案示例导入 Koa 解决了这个问题。有关更多信息,我也刚刚遇到了这个高度相关的问题github.com/Microsoft/TypeScript/issues/10859
    【解决方案2】:

    将类型添加到koa-bearer-token.d.ts 的另一种更可扩展的解决方案是添加一个类似koa-extensions.d.ts 的文件,并在那里添加任何额外的属性,如下所示:

    import {Context, Request} from 'koa';
    
    declare namespace KoaExtensions {
        interface KoaRequest extends Request {
            token?: string
        }
    
        interface KoaContext extends Context {
            request: KoaRequest
        }
    }
    
    export = KoaExtensions;
    

    然后就可以导入扩展类型了:

    import {KoaContext} from './@types/koa-extensions';
    const someFunction = (ctx: KoaContext) => {
        const token = ctx.request.token; // <-- No longer errors
    };
    

    这是对我最初解决方案的改进,但似乎我应该能够在本地 koa.d.ts 文件中全局扩充 Koa 模块类型。

    【讨论】:

      【解决方案3】:

      我需要做同样的事情来为 Knockout 添加一些东西。我创建了一个my-ko-additions.d.ts 文件并以与完成敲除声明相同的方式实现它:

      interface KnockoutStatic {
          additionalFunc1(input: string): string;
          additionalFunc2(input: string): string;
      }
      
      declare var ko: KnockoutStatic;
      
      declare module "knockout" {
          export = ko;
      }
      

      然后我只需说ko.additionaFunc1('abc')就可以实现和使用这些功能。

      【讨论】:

        猜你喜欢
        • 2020-12-09
        • 1970-01-01
        • 2019-04-01
        • 2018-02-26
        • 2017-08-30
        • 2018-05-28
        • 1970-01-01
        • 2017-12-03
        • 1970-01-01
        相关资源
        最近更新 更多