首页 文章

在TypeScript中使用导入类型的环境声明

提问于
浏览
11

我在我的TypeScript项目中有一个声明文件,如下所示:

// myapp.d.ts
declare namespace MyApp {
  interface MyThing {
    prop1: string
    prop2: number
  }
}

这很好用,我可以在项目的任何地方使用这个命名空间,而无需导入它 .

我现在需要从第三方模块导入一个类型并在我的环境声明中使用它:

// myapp.d.ts
import {SomeType} from 'module'

declare namespace MyApp {
  interface MyThing {
    prop1: string
    prop2: number
    prop3: SomeType
  }
}

编译器现在抱怨它找不到命名空间'MyApp',大概是因为导入阻止它成为环境 .

在使用第三方类型时,是否有一些简单的方法可以保留声明的环境效果?

2 回答

  • 1

    是的,有一种方法 . 使用import() a type在TypeScript 2.9中会变得更容易,但在早期版本的TypeScript中也是如此 .

    以下文件是一个脚本 . 脚本中声明的内容将添加到全局范围 . 这就是为什么你可以使用 MyApp.MyThing 而不导入它 .

    // myapp.d.ts
    declare namespace MyApp {
      interface MyThing {
        prop1: string;
        prop2: number;
      }
    }
    

    脚本是有限的,因为它们不能导入任何东西;当您添加 import 时,脚本将成为模块 . 我认为至少可以说是奇怪的,但事实就是如此 . 重要的是模块中定义的内容范围限定为该模块,并且不会添加到全局范围 .

    但是,模块也可以将声明添加到全局范围,方法是将它们放在 global 中:

    // myapp.d.ts
    import {SomeType} from 'module';
    
    declare global {
      namespace MyApp {
        interface MyThing {
          prop1: string;
          prop2: number;
          prop3: SomeType;
        }
      }
    }
    

    此文件是一个模块,但它将 MyApp.MyThing 的声明添加到全局范围,因此您仍然可以在其他TypeScript代码中使用 MyApp.MyThing 而无需导入它 .

    请注意,使用 .d.ts 扩展名与您无需导入即可访问界面无关 . 上述两个文件都可能是 .ts 文件,但仍然表现完全相同 .

  • 13

    很不幸的是,不行 . 正如您已经发现的那样,这只适用于内部代码,例如:没有外部依赖 . 您应该导出命名空间,或者导出类并使用ES6模块 . 但两者都会导致你需要 import 你的东西 . 正如我所相信的,你正试图避免的事情 .

    就个人而言,我发现在整个代码中实际使用导入(甚至内部)更令人感到欣慰 . 这是因为打开特定文件(类)时,所有依赖项都立即可见 .

    "How to use namespaces with import in TypeScript"问题中已经解决了一个彻底的例子 .

    对其他人的注意:“内部可用命名空间”也是我不认为这是一个重复问题的原因 .

相关问题