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关键字的含义是什么?
type Callback = (err: Error | String, data: Array<CalledBackData>) => void;
vs.
declare type Callback = (err: Error | String, data:Array<CalledBackData>) => void;
在TS中找不到解释declare关键字目的的文档。Qué signa ?
当前回答
博士TL;
declare用来告诉编译器“这个东西(通常是一个变量)已经存在,因此可以被其他代码引用,也不需要将这条语句编译成任何JavaScript”。
常用用例:
你将网页的引用添加到一个JavaScript文件中,而编译器对此一无所知。也许它是来自其他域的脚本,如“foo.com”。当被求值时,脚本将创建一个带有一些有用API方法的对象,并将其分配给全局作用域中的标识符'fooSdk'。
你希望你的TypeScript代码能够调用fooSdk. dosomething(),但是由于你的编译器不知道fooSdk变量的存在,你会得到一个编译错误。
然后使用declare关键字告诉编译器“相信我,这个变量存在并且具有这种类型”。编译器将使用此语句静态检查其他代码,但不会将其转编译为输出中的任何JavaScript。
declare const fooSdk = { doSomething: () => boolean }
较新的Typescript版本需要稍微不同的语法:
declare const fooSdk : { doSomething: () => boolean }
同样,您可以向类属性添加declare关键字,以告诉编译器不要发出任何会创建此属性的代码,假设您有自己的代码会创建编译器不知道或不理解的属性。
您的具体示例有所不同,因为您声明的是类型,而不是变量,类型已经不会编译到任何JavaScript中。我不知道是否有任何理由声明一个类型。
其他回答
考虑这个场景:您有一个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不会抱怨任何事情,因为它现在可以访问类型了。
博士TL;
declare用来告诉编译器“这个东西(通常是一个变量)已经存在,因此可以被其他代码引用,也不需要将这条语句编译成任何JavaScript”。
常用用例:
你将网页的引用添加到一个JavaScript文件中,而编译器对此一无所知。也许它是来自其他域的脚本,如“foo.com”。当被求值时,脚本将创建一个带有一些有用API方法的对象,并将其分配给全局作用域中的标识符'fooSdk'。
你希望你的TypeScript代码能够调用fooSdk. dosomething(),但是由于你的编译器不知道fooSdk变量的存在,你会得到一个编译错误。
然后使用declare关键字告诉编译器“相信我,这个变量存在并且具有这种类型”。编译器将使用此语句静态检查其他代码,但不会将其转编译为输出中的任何JavaScript。
declare const fooSdk = { doSomething: () => boolean }
较新的Typescript版本需要稍微不同的语法:
declare const fooSdk : { doSomething: () => boolean }
同样,您可以向类属性添加declare关键字,以告诉编译器不要发出任何会创建此属性的代码,假设您有自己的代码会创建编译器不知道或不理解的属性。
您的具体示例有所不同,因为您声明的是类型,而不是变量,类型已经不会编译到任何JavaScript中。我不知道是否有任何理由声明一个类型。
你可以在编写任何实现代码之前使用declare告诉编译器类型,TypeScript会很高兴。
declare function foo(name: string): string
当您导入一些没有声明类型文件的库时,如*.d.ts,使用Delcare关键字
之后vs eslint不检查语法和上下文,会让你通过,如果你默认使用TSC编译器,那就有很好的理由声明删除语法错误
这里有一个真实的例子。
我有一个使用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”在公认答案中的意思。