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

使用TypeScript中导入的类型的环境声明,typescript,Typescript,我的TypeScript项目中有一个声明文件,如下所示: // myapp.d.ts declare namespace MyApp { interface MyThing { prop1: string prop2: number } } 这非常有效,我可以在项目中的任何地方使用这个名称空间,而无需导入它 我现在需要从第三方模块导入一个类型,并在环境声明中使用它: // myapp.d.ts import {SomeType} from 'module' decla

我的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”,可能是因为导入阻止了它成为环境名称空间


在使用第三方类型的同时,是否有一些简单的方法来保持声明的环境友好性?

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

就我个人而言,我觉得在整个代码中实际使用导入(甚至内部)更令人欣慰。原因很简单,当打开一个特定的文件(类)时,它的所有依赖项都立即可见

问题中已经提到了一个彻底的例子


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

是的,有办法。在TypeScript 2.9中,通过使用,它变得更容易,但在早期版本的TypeScript中也可以这样做

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

// myapp.d.ts
declare namespace MyApp {
  interface MyThing {
    prop1: string;
    prop2: number;
  }
}
脚本受到限制,因为它们不能导入任何内容;添加
导入时
,脚本将成为一个模块。我觉得至少可以说这很奇怪,但事实就是这样。重要的是,模块中定义的内容被限定在该模块的范围内,而不是添加到全局范围内

但是,模块也可以将声明添加到全局范围中,方法是将它们放在
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
,而无需导入它

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

请注意,使用
.d.ts
扩展与不导入接口就可以访问接口无关。上述两个文件可能都是
.ts
文件,但其行为仍然完全相同。

由于ts 2.9,这可以通过
导入()
实现:

//myapp.d.ts
声明类型SomeType=import('module')。SomeType;
声明类型SomeDefaultType=import('module-with-default-export')。默认值;
声明命名空间MyApp{
界面神话{
prop1:字符串;
建议2:数字;
prop3:SomeType | SomeDefaultType;
}
}

不知道您是否仍在寻找答案,但这是正确的处理方法,并且仍然能够定义通用模块,而不仅仅是命名名称空间:


@RomanStarkov这对于任何任意库都是不可能的,你有没有一个特别的库?@TitianCernicova Dragomir,比如说
luxon
,它带有打字功能,看起来就像这里的示例代码-
import{DateTime}from'luxon'
。谢谢。我已经寻找这个解决方案一个多小时了。我无法理解为什么很难与一个向全局范围添加符号但不能使用常规模块导入的环境集成,特别是因为这似乎是一个非常普遍的要求……将其包装在
全局
中确实需要更广为人知。这是一种非常常见的情况,很多答案都忽略了这一简单的修复。2.9功能是否允许以某种方式将导入的模块定义(具有外部模块格式)中的所有内容声明为全局(例如,所有类型、接口、变量)?我希望我能对此进行1000次升级。我一直在纠结。这仍然需要在某个地方导入myapp.d.ts以使全局增强工作?
声明类型Foo=import('someModule')。默认值给我一个错误,即使
“someModule”
定义了默认导出:“命名空间'someModule'没有导出的成员'default'。这是不正确的。至少在使用Typescript 3.8/3.9时是这样。它将给您一个错误
名称空间中的导入声明不能引用模块。