【问题标题】:Error TS2497: Module '...' resolves to a non-module entity and cannot be imported using this construct错误 TS2497:模块“...”解析为非模块实体,无法使用此构造导入
【发布时间】:2017-12-12 03:30:23
【问题描述】:

给定这个声明文件promise-retry/index.d.ts,它遵循TypeScript官方的module-function.d.ts格式:

编辑: 之前为此粘贴了错误的代码段(在下方仍然可见)

export = promiseRetry;

declare function promiseRetry(options: Partial<PromiseRetry.NodeRetryOptions>, fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>): Promise<any>;
declare function promiseRetry(fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>, options ?: Partial<PromiseRetry.NodeRetryOptions>): Promise<any>;

declare namespace PromiseRetry {
    export interface NodeRetryOptions {
        forever: boolean;
        unref: boolean;
        retries: number;
        factor: number;
        minTimeout: number;
        maxTimeout: number;
        randomize: number | false;
    }

    export type RetryFn = (err: any) => never;
}

我发现我无法通过以下语法导入 NodeRetryOptionsRetryFn

import {NodeRetryOptions, RetryFn} from "promise-retry";

let options: NodeRetryOptions = { forever: false };
let retryFn: RetryFn = (err:any)=>{throw "Nobody responds on StackOverflow"};

...因为它引发编译错误:error TS2497: Module '"promise-retry"' resolves to a non-module entity and cannot be imported using this construct.

我还尝试了另一种语法:

declare module "promise-retry" {
    export = promiseRetry;

    function promiseRetry(options: Partial<PromiseRetry.NodeRetryOptions>, fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>): Promise<any>;
    function promiseRetry(fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>, options ?: Partial<PromiseRetry.NodeRetryOptions>): Promise<any>;

    namespace PromiseRetry {
        export interface NodeRetryOptions {
            forever: boolean;
            unref: boolean;
            retries: number;
            factor: number;
            minTimeout: number;
            maxTimeout: number;
            randomize: number | false;
        }

        export type RetryFn = (err: any) => never;
    }
}

但是导入(以不同的方式)也失败了:

import * as PromiseRetry from "promise-retry";

let options: PromiseRetry.NodeRetryOptions = { forever: false };
let retryFn: PromiseRetry.RetryFn = (err:any)=>{throw "Nobody responds on StackOverflow"};

...抛出完全相同的编译器错误。

我已经阅读了我能找到的所有内容(包括此处的相关链接),但我无法正常工作。用特朗普的话来说,“没有人知道 TypeScript 导入会如此复杂。”

【问题讨论】:

    标签: typescript types typescript-typings definitelytyped


    【解决方案1】:

    example you linked to 在其 cmets 中有一个重要说明:

    /*~ Note that ES6 modules cannot directly export callable functions.
     *~ This file should be imported using the CommonJS-style:
     *~   import x = require('someLibrary');
     *~
     *~ Refer to the documentation to understand common
     *~ workarounds for this limitation of ES6 modules.
     */
    

    您可能想要的是以下内容:

    export = PromiseRetry;
    
    declare function PromiseRetry(options: Partial<PromiseRetry.NodeRetryOptions>, fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>): Promise<any>;
    declare function PromiseRetry(fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>, options ?: Partial<PromiseRetry.NodeRetryOptions>): Promise<any>;
    
    declare namespace PromiseRetry {
        export interface NodeRetryOptions {
            forever: boolean;
            unref?: boolean;
            retries?: number;
            factor?: number;
            minTimeout?: number; // milliseconds
            maxTimeout?: number; // milliseconds|(Number.)Infinity, which is itself of number type.
            randomize?: number | false;
        }
    
        export type RetryFn = (err: any) => never;
    }
    

    注意大写的PromiseRetry 函数以匹配命名空间。然后,要导入,请使用以下行:

    import PromiseRetry = require('promise-retry');
    

    然后,用法必须以命名空间作为前缀:

    let options: PromiseRetry.NodeRetryOptions = { forever: false };
    let retryFn: PromiseRetry.RetryFn = (err:any) => {throw "Sometimes people respond on StackOverflow"};
    

    附带说明一下,似乎大多数包都倾向于使用命名空间来附加类型作为函数声明的命名空间子项。另一个允许您为函数和命名空间使用不同名称的替代方法如下:

    export declare function promiseRetry(options: Partial<PromiseRetry.NodeRetryOptions>, fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>): Promise<any>;
    export declare function promiseRetry(fn: (retry: PromiseRetry.RetryFn, attempt: number) => Promise<any>, options ?: Partial<PromiseRetry.NodeRetryOptions>): Promise<any>;
    
    declare namespace PromiseRetry {
        export interface NodeRetryOptions {
            forever: boolean;
            unref?: boolean;
            retries?: number;
            factor?: number;
            minTimeout?: number; // milliseconds
            maxTimeout?: number; // milliseconds|(Number.)Infinity, which is itself of number type.
            randomize?: number | false;
        }
    
        export type RetryFn = (err: any) => never;
    }
    

    【讨论】:

    • 感谢您的详细回复。您的第一个选项使用建议的 import PromiseRetry = require("promise-retry");,适用于 PromiseRetry() 调用,但会抛出 "cannot find namespace 'PromiseRetry'" 以供 PromiseRetry.NodeRetryOptions 使用。第二个选项适用于promiseRetry() 调用,但再次引发相同的错误。在declare namespace PromiseRetry 之前添加export 对此错误没有影响。你觉得我应该怎么做?
    猜你喜欢
    • 2016-05-18
    • 2019-01-29
    • 2017-01-17
    • 2018-04-04
    • 2023-03-15
    • 2016-04-19
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    相关资源
    最近更新 更多