TypeScript中的clarify关键字的用途


89

declare关键字的目的是什么?

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

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

找不到说明declareTS中关键字目的的文档。

Answers:


98

这是一个真实的例子。

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

当我运行代码时,module来自Webpack Hot Middleware的对象存在,并且尽管它是隐藏在我新的TypeScript React应用程序中的很好的老式JavaScript,但我可以进行console.log记录。

module对象还具有键,例如module.hot,并且键可以具有值。但是TypeScript设计时编译器(至少在VSCode中)在其下写着一个红色的波浪形property 'hot' does not exist。但是它确实存在!

为了使TypeScript编译器达成一致,请这样声明:

declare let module: any

现有module对象现在的类型为any,这使TypeScript编译器现在感到满意,红色弯弯曲曲地消失了,现在我可以继续编译并编写其他代码了。

如果删除关键字declare并仅编写let module: any,它将不会编译,而是说'module' already exists。这就是被接受的答案中“环境”的含义。


32
declare为现有变量指定类型,而不声明新变量。
丹农

2
@Danon-并且答案..
ortonomy

60

tl; dr

“ declare”用于告诉编译器“此事物(通常是变量)已经存在,因此可以被其他代码引用,也无需将该语句编译为任何JavaScript”

常见用例:

您将对网页的引用添加到编译器一无所知的JavaScript文件中。也许这是一个来自其他域名(例如“ foo.com”)的脚本。经过评估,脚本将创建并使用一些有用的api方法进行对象化,并将其分配给全局范围内的标识符'fooSdk'。

您希望您的TypeScript代码能够调用“ fooSdk.doSomething()”,但由于编译器不知道此变量存在,因此会出现编译错误。

然后,您可以使用声明关键字作为告诉编译器“相信我,此变量存在并且具有这种类型”的方式。编译器将使用此语句来静态检查其他代码,但不会将其反编译为输出中的任何JavaScript。

declare const fooSdk = { doSomething: () => boolean };

同样,您可以在类属性中添加define关键字,以告诉编译器不要发出任何会创建此属性的代码,前提是您拥有自己的代码会创建该属性,而编译器对此并不了解或不理解。

您的特定示例有所不同,因为您声明的是类型,而不是变量,所以类型已经不能编译为任何JavaScript。我不知道是否有任何理由来声明类型。


5

来自Typescript文档:

打字稿-使用其他JavaScript库

为了描述不是用TypeScript编写的库的形状,我们需要声明该库公开的API。因为大多数JavaScript库仅公开一些顶级对象,所以名称空间是表示它们的好方法。

我们将没有定义实现的声明称为“环境”。通常,这些文件在.d.ts文件中定义。如果您熟悉C / C ++,则可以将它们视为.h文件。让我们看几个例子。

环境命名空间

流行的库D3在称为d3的全局对象中定义其功能。由于此库是通过标签(而不是模块加载器)加载的,因此其声明使用名称空间来定义其形状。为了让TypeScript编译器看到这种形状,我们使用环境名称空间声明。例如,我们可以开始编写如下代码:

D3.d.ts(简体摘录)

declare namespace D3 {
    export interface Selectors {
        select: {
            (selector: string): Selection;
            (element: EventTarget): Selection;
        };
    }
    // (...)
}

1

您可以在编写任何实现代码之前使用声明来告诉编译器有关类型的信息,TypeScript会很高兴。

declare function foo(name: string): string

0

导入某些没有声明类型文件的库时使用的delcare关键字,例如* .d.ts

之后,vs eslint不检查语法和上下文,将让您通过,如果您默认使用tsc编译器,则声明删除语法错误的充分理由


这是不正确的。define关键字不是用于此目的,而是在该方案中使用。
SgtPooki
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.