如何导入其顶级元素是非导出命名空间的Typescript类型定义文件?

时间:2017-12-15 04:59:30

标签: typescript namespaces typescript-definitions

我试图使用@types/googlemaps类型定义文件。

代码看起来像

declare namespace google.maps {
    /***** Map *****/
    export class Map extends MVCObject {
        constructor(mapDiv: Element|null, opts?: MapOptions);
        fitBounds(bounds: LatLngBounds|LatLngBoundsLiteral): void;
        ...
        ...
        overlayMapTypes: MVCArray<MapType>;
    }

    export interface MapOptions {
        backgroundColor?: string;
        disableDoubleClickZoom?: boolean;
        draggable?: boolean;
        ...

当我尝试在我的项目中使用此类型定义时,如此

import * as google from 'googlemaps';

我收到编译错误

Error:(2, 25) TS2306:File 'C:/Users/CodyB/musicappproj/src/node_modules/@types/googlemaps/index.d.ts' is not a module.

为什么不将此类型定义文件视为模块? 我用错了吗?定义文件错了吗?

1 个答案:

答案 0 :(得分:1)

  

为什么不将这个类型定义文件视为模块?

编译器不将此类型定义文件视为ECMA6模块,因为该文件缺少顶层导出/导入。相反,文件将其导出嵌套/隐藏在{{1 }},并且不会导出名称空间。结果,名称空间成为全局范围的一部分,并且文件不成为模块。

仅当文件具有顶级导入或导出时,它才是模块。在以下代码中,namespacefoo.ts都是模块,但bar.ts不是模块,因为它缺少顶级baz.tsimport语句。 / p>

export
  

我使用错了吗?

是的。您正在像对待文件一样对待文件-事实并非如此。另一种方法是通过其定义的全局名称空间访问其成员。这是两种方法:

一种方法是像这样“点进”命名空间:

// foo.ts
console.log('foo');
export {}

// bar.ts
import * as foo from './foo';
console.log('bar');

// baz.ts
console.log('baz');

// index.ts
import * as foo from './foo';
import * as bar from './bar';
import * as baz from './baz'; // File 'c:/dev/temp/baz.ts' is not a module.ts(2306)

另一种方法是使用这种破坏:

const div1 = new HTMLDivElement();
const map1 = new google.maps.Map(div1);
  

定义文件是否错误?

不。尽管可以说对于浏览器(例如Firefox)应用程序来说,它比对NodeJS应用程序更传统,但它正在采取一种有效的方法。

另请参见:

https://www.typescriptlang.org/docs/handbook/namespaces.html

https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html