在 Typescript 中重载全局函数时的引用模块

Reference module when overloading a global function in Typescript

我正在使用 moment.js(具体来说,moment-timezone),它有一个名为 Duration 的接口。 Duration.prototype.valueOf() returns 一个数字,所以在 JavaScript 中调用

setInterval(myCallback, moment.duration(30, 'seconds'));

工作正常。

我想编写一个允许这样做的 TypeScript 声明文件。

global.d.ts

export {};

declare global {
    function setTimeout(callback: (...args: any[]) => void, ms: Duration, ...args: any[]): NodeJS.Timeout;

    function setInterval(callback: (...args: any[]) => void, ms: Duration, ...args: any[]): NodeJS.Timeout;
}

当我前置时

import { Duration } from 'moment-timezone';

它将 .d.ts 文件视为模块声明,因此它不会影响全局命名空间。

我想将 import 移到 declare global 范围内,但它仍然将 Duration 视为 any

我也试过了

/// <reference path="node_modules/@types/moment-timezone/index.d.ts" />

但这似乎没有任何作用。

我看到一些答案提到了 tsconfig.json 中的设置,但这对我来说不是一个选项,而且这看起来确实应该是首先可能的。

这需要两个步骤:

  1. declare global 范围外声明模块。
  2. import 放在 declare global 范围内。

对于 OP 示例:

export {}

declare module 'moment-timezone';

declare global {
    import { Duration } from 'moment-timezone';

    function setTimeout(callback: (...args: any[]) => void, ms: Duration, ...args: any[]): NodeJS.Timeout;

    function setInterval(callback: (...args: any[]) => void, ms: Duration, ...args: any[]): NodeJS.Timeout;
}

如果您想将自己的类型导入外部模块,请将 import 放在 declare module 范围内,并确保您的类型在它们的 declare module 范围内拥有。

typings/my-custom-types.d.ts

declare module 'my-custom-types' { // <-- this was the missing line that was giving me trouble
    export interface MyStringInterface {
        valueOf(): string;
    }
}

typings/some-lib/index.d.ts

declare module 'some-lib' {
    import { MyStringInterface } from 'my-custom-types';

    export interface SomeExistingClass {
        // Add your own signatures
        someExistingMethod(stringParam: MyStringInterface): any;
    }
}