declare关键字的含义是什么?

type Callback = (err: Error | String, data: Array<CalledBackData>) => void;

vs.

declare type Callback = (err: Error | String, data:Array<CalledBackData>) => void;

在TS中找不到解释declare关键字目的的文档。Qué signa ?


当前回答

你可以在编写任何实现代码之前使用declare告诉编译器类型,TypeScript会很高兴。

declare function foo(name: string): string

其他回答

来自Typescript文档:

Typescript -使用其他JavaScript库

To describe the shape of libraries not written in TypeScript, we need to declare the API that the library exposes. Because most JavaScript libraries expose only a few top-level objects, namespaces are a good way to represent them. We call declarations that don’t define an implementation “ambient”. Typically these are defined in .d.ts files. If you’re familiar with C/C++, you can think of these as .h files. Let’s look at a few examples. Ambient Namespaces The popular library D3 defines its functionality in a global object called d3. Because this library is loaded through a tag (instead of a module loader), its declaration uses namespaces to define its shape. For the TypeScript compiler to see this shape, we use an ambient namespace declaration. For example, we could begin writing it as follows: D3.d.ts (simplified excerpt) declare namespace D3 { export interface Selectors { select: { (selector: string): Selection; (element: EventTarget): Selection; }; } // (...) }

这里有一个真实的例子。

我有一个使用Webpack热中间件的TypeScript React应用程序。Webpack热中间件不是用TypeScript编写的,而是用老式的JavaScript编写的。所以它没有TypeScript编译器可以检查的类型声明。

当我运行我的代码时,来自Webpack热中间件的对象模块存在,我可以console.log它,尽管它是隐藏在我漂亮的新TypeScript React应用程序中的老式JavaScript。

模块对象也有键,比如module. key。Hot,键可以有值。但是TypeScript设计时编译器(至少在VSCode中)在它下面画了一个红色的曲线,表示属性“hot”不存在。但它确实存在!

为了让TypeScript编译器同意,像这样声明它:

declare let module: any

现有的模块对象,现在有了any类型,这让TypeScript编译器很高兴,红色曲线消失了,现在我可以继续编译并编写其他代码。

如果你删除关键字declare,只写let module: any,它不会编译,而是说'module'已经存在。这就是“ambient”在公认答案中的意思。

考虑这个场景:您有一个Typescript项目。然后,不管出于什么原因,你决定用JavaScript编写一个模块,并在Typescript代码中使用它。

// getMyName.js
module.exports = function getMyName(name) {
    return name;
}

然后将它导入typescript代码中

// myCode.ts
import getMyName from 'getMyName'; //getMyName is a JS module not typescript

当导入该JS模块时(allowJs编译器选项应该设置为false,否则JS文件将在没有任何类型定义的情况下被解析),Typescript的编译器会抱怨该模块根本不是模块!

找不到模块“/absolute/path/to/getMyName.ts”的声明文件

这是因为Typescript不会自行解析为JS代码。为了避免这个问题,我们应该为JS模块提供类型定义(filename.d.ts)。为此,您可以使用声明和导出。

// getMyName.d.ts
declare function getMyName(name: string): string;

export default getMyName;

之后,当我们导入JS模块时,typescript不会抱怨任何事情,因为它现在可以访问类型了。

当您导入一些没有声明类型文件的库时,如*.d.ts,使用Delcare关键字

之后vs eslint不检查语法和上下文,会让你通过,如果你默认使用TSC编译器,那就有很好的理由声明删除语法错误

你可以在编写任何实现代码之前使用declare告诉编译器类型,TypeScript会很高兴。

declare function foo(name: string): string