如何导入其顶级元素是未导出的命名空间的Typescript类型定义文件? [英] How do you import a Typescript type definition file whose top level element is a non-exported namespace?

查看:227
本文介绍了如何导入其顶级元素是未导出的命名空间的Typescript类型定义文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 @types/googlemaps 类型定义文件.

I'm trying to use the @types/googlemaps type definition file.

代码看起来像

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;
        ...

当我尝试在项目中使用此类型定义时,就像这样

When I try to use this type definition in my project, like so

import * as google from 'googlemaps';

我收到一个编译错误,说

I get a compile error saying

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

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

Why does it not consider this types definition file to be a module? Am I using it wrong ? Is the definition file wrong?

推荐答案

为什么它不将此类型定义文件视为模块?

Why does it not consider this types definition file to be a module?

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

The compiler does not consider this type definition file to be an ECMA6 module because the file lacks a top-level export/import. Instead, the file nests/hides its exports inside a namespace and does not export the namespace. As a result, the namespace becomes part of the global scope, and the file does not become a module.

仅当文件具有顶级导入或导出时,它才是模块.在下面的代码中,foo.tsbar.ts都是模块,但是baz.ts不是模块,因为它缺少顶级的importexport语句.

A file is a module only if it has a top-level import or export. In the following code, both foo.ts and bar.ts are modules, but baz.ts is not, because it lacks a top-level import or export statement.

// 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)

我使用错了吗?

Am I using it wrong?

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

Yes. You are treating the file like it is a module - which it is not. The alternative is to access its members through the global namespace it defines. Here are two approaches:

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

One is to 'dot into' the namespace like this:

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

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

Another is to use destructuring like this:

const { Map } = google.maps;
const div2 = new HTMLDivElement();
const map2 = new Map(div2);

定义文件是否错误?

Is the definition file wrong?

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

No. It is taking a valid approach albeit one that is arguably more conventional for a browser (e.g. Firefox) application than it is for a NodeJS application.

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

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

这篇关于如何导入其顶级元素是未导出的命名空间的Typescript类型定义文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆