【问题标题】:Typescript: how to declare namespace with import statement?Typescript:如何使用 import 语句声明命名空间?
【发布时间】:2022-01-27 00:20:51
【问题描述】:

我正在使用 cypress 并声明命名空间来推断自定义命令的类型。

index.d.ts

declare namespace Cypress {
  interface Chainable {
    commandA: typeof commandA;
  }
}

commands.ts

const commandA = ...;

Cypress.commands.add('commandA', commandA);

在这种情况下,我必须在cypress/types/net-stubbing 包中使用CyHttpMessages 类型。所以我将该类型导入commands.ts 文件中。

commands.ts(带导入)

import { CyHttpMessages } from 'cypress/types/net-stubbing';

...

但是,在导入该类型 index.d.ts 后,文件被红线破坏了。此文件找不到 commandA 函数的类型。我认为import 声明是导致此问题的原因。

如何将 import 语句与 declare namespace 一起使用?问题是什么?感谢您的阅读。

【问题讨论】:

  • 我也有同样的问题????搞清楚有什么进展吗?
  • 您好,您能否为我创建一个最小的可重现示例?我曾经在playwright 固定装置上遇到过与您类似的问题,我通过一些奇怪的魔法解决了它。项目配置非常具体,所以我不确定它是否会在没有进一步上下文的情况下适用于这里:)。

标签: typescript namespaces


【解决方案1】:

为自定义 Cypress 命令设置 Typescript 定义时,您需要使用 declare global {}。

documentation provides an example,但根据提供的信息,它应该如下所示:

index.d.ts

/// <reference types="cypress" />

declare global {
  namespace Cypress {
    interface Chainable {
      commandA(): Chainable<Element>
    }
  }
}

【讨论】:

    【解决方案2】:

    带有命名空间的解决方案(不推荐) 要解决您的问题,您可以导出命名空间:

    // UtilBase.ts
    import * as path from "path";
    export namespace My.utils {
        export class UtilBase {
            protected fixPath(value: string): string {
                return value.replace('/', path.sep);
            }
       }
    }
    

    然后,你应该可以导入它了:

    // UtilOne.ts
    import {My} from './UtilBase';
    namespace My.utils {
        export class UtilOne extends My.utils.UtilBase {
        }
    }
    

    但是,如果目的是组织代码,那么同时使用命名空间和 (ES6) 模块是一种不好的做法。使用 Node.js,你的文件是模块,那么你应该避免命名空间。

    使用没有命名空间的 ES6 模块 TypeScript 非常支持 ES6 模块的语法:

    // UtilBase.ts
    import * as path from "path";
    export default class UtilBase {
        protected fixPath(value: string): string {
            return value.replace('/', path.sep);
        }
    }
    
    // UtilOne.ts
    import UtilBase from './UtilBase';
    export default class UtilOne extends UtilBase {
    }
    

    这是推荐的方式。 ES6 模块通过重命名每个导入资源的能力来防止命名冲突。

    使用文件 tsconfig.json 而不是 ///

    // tsconfig.json
    
    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "es6"
      },
      "exclude": [
        "node_modules"
      ]
    }
    

    这是来自另一个答案,here。

    【讨论】:

      猜你喜欢
      • 2011-07-06
      • 1970-01-01
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 2021-01-13
      • 2019-02-05
      • 2015-01-07
      相关资源
      最近更新 更多