typescript “声明”在“导出声明类操作”中有什么作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35019987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:52:49  来源:igfitidea点击:

What does 'declare' do in 'export declare class Actions'?

typescript

提问by born2net

Why do we need the declarein the statement?

为什么我们需要declare在语句中?

export declare class Actions {
    ...
}

回答by born2net

found what I was looking for:

找到了我要找的东西:

Declare vs. var

声明与 var

varcreates a new variable. declareis used to tell TypeScript that the variable has been created elsewhere. If you use declare, nothing is added to the JavaScript that is generated - it is simply a hint to the compiler.

var创建一个新变量。declare用于告诉 TypeScript 该变量已在别处创建。如果使用declare,则不会向生成的 JavaScript 添加任何内容 - 它只是对编译器的提示。

For example, if you use an external script that defines var externalModule, you would use declare var externalModuleto hint to the TypeScript compiler that externalModulehas already been set up

例如,如果您使用定义 的外部脚本var externalModule,您将使用declare var externalModule提示externalModule已设置的 TypeScript 编译器

回答by Terrence

To understand this, you have to first understand the "declare" keyword.

要理解这一点,您必须首先理解“declare”关键字。

Here is a good explanation from Gil Fink's Blog:

以下是Gil Fink 博客的一个很好的解释:

The TypeScript declare keyword is used to declare variables that may not have originated from a TypeScript file.

TypeScript declare 关键字用于声明可能并非源自 TypeScript 文件的变量。

For example, lets imagine that we have a library called myLibrary that doesn't have a TypeScript declaration file and have a namespace called myLibrary in the global namespace. If you want to use that library in your TypeScript code, you can use the following code:

declare var myLibrary;

The type that the TypeScript runtime will give to myLibrary variable is the any type. The problem here is that you won't have Intellisense for that variable in design time but you will be able to use the library in your code. Another option to have the same behavior without using the declare keyword is just using a variable with the any type:

var myLibrary: any;

Both of the code examples will result in the same JavaScript output but the declare example is more readable and expresses an ambient declaration.

例如,假设我们有一个名为 myLibrary 的库,它没有 TypeScript 声明文件,并且在全局命名空间中有一个名为 myLibrary 的命名空间。如果要在 TypeScript 代码中使用该库,可以使用以下代码:

declare var myLibrary;

TypeScript 运行时将赋予 myLibrary 变量的类型是 any 类型。这里的问题是在设计时你不会有该变量的智能感知,但你将能够在你的代码中使用该库。不使用声明关键字而具有相同行为的另一种选择是仅使用具有 any 类型的变量:

var myLibrary: any;

这两个代码示例将产生相同的 JavaScript 输出,但declare 示例更具可读性并表达了环境声明。



So after you understand the "declare" keyword, go back to wherever you find the

所以在你理解了“declare”关键字之后,回到你找到的地方

export declare class Action{
...
}

The class's real implementation is probably in somewhere else—maybe a .js file.

该类的真正实现可能在其他地方——可能是一个 .js 文件。

回答by Willem van der Veen

declarein typescript:

declare在打字稿中:

The declarekeyword in typescript is useful for telling the typescript compiler that a declarationis defined somewhere else (somewhere written in an external javascript file or part of the runtime environment).

declaretypescript 中的关键字对于告诉 typescript 编译器在其他地方(在外部 javascript 文件或运行时环境的一部分中编写的某处)定义了一个声明很有用。

Let's say we have a variable called foo declared somewhere else. When we then try to reference the variable the typescript compiler will throw an error:

假设我们在其他地方声明了一个名为 foo 的变量。当我们尝试引用变量时,typescript 编译器会抛出一个错误:

foo = 'random'; // Error: 'foo' is not defined

We can fix this problem using the declarekeyword:

我们可以使用declare关键字来解决这个问题:

declare var foo: string;
foo = 'random';  // no error anymore

This has the following consequences:

这有以下后果:

  • When fooactually isn't declared anywhere else, and we try to use the variable a runtime error might occur. So only use the declarekeyword when you know the variable is available at this point.
  • Because we know the types, we (potentially) get access to our IDE Intellisense.
  • Because we know the types, the typescript compiler can check the types at compile time, and can warn us if we are using the wrong types in certain scenarios.
  • 如果foo实际上没有在其他任何地方声明,并且我们尝试使用该变量,则可能会发生运行时错误。因此,仅declare当您知道此时变量可用时才使用关键字。
  • 因为我们知道类型,所以我们(可能)可以访问我们的 IDE Intellisense
  • 因为我们知道类型,打字稿编译器可以在编译时检查类型,如果我们在某些情况下使用了错误的类型,可以警告我们。

回答by André Pena

The declarekeyword in this specific case:

在这种特定情况下的声明关键字:

export declare class Actions {
    ...
}

... is apparently useless and I think TypeScript should consider making this an error (I don't know if there's a hidden reason). If you declare a class, you will never need to import it. If you export a class expecting someone to import it, you don't need to declare it. And because you are declaring this class, by definition, this class should be usable without the need to import it. But this is not true when you export declarea class. You needto import it to use.

...显然没用,我认为 TypeScript 应该考虑将此作为错误(我不知道是否有隐藏的原因)。如果你声明一个类,你将永远不需要导入它。如果您导出一个类希望有人导入它,则不需要声明它。并且因为您要声明这个类,所以根据定义,这个类应该可以使用而无需导入它。但是当您导出声明一个类时,情况并非如此。您需要导入它才能使用。

TL;DR

TL; 博士

export declare class Actions {
    ...
}

is the same as

是相同的

declare class Actions {
    ...
}

回答by pierpytom

declare- without any import or export keywords - defines declaration files automatically picked by TypeScript, which is an useful feature to add typing to legacy modules (npm installed packages without TypeScript definitions).

declare- 没有任何导入或导出关键字 - 定义由 TypeScript 自动选取的声明文件,这是向遗留模块(npm 安装的没有 TypeScript 定义的包)添加类型的有用功能。

import/ exportis the proper way to use modules, and everything needs to be manually (and I find a bit tediously) imported, either it's logic, either it's definitions.

import/export是使用模块的正确方法,一切都需要手动(我觉得有点乏味)导入,要么是逻辑,要么是定义。

As a practical use case, export declareallows you to avoid exporting all the sub-elements, e.g.:

作为一个实际用例,export declare允许您避免导出所有子元素,例如:

export declare namespace Redux {
    namespace Store {
        interface Definition { ... }
    }
}

Which may be easier to read than:

这可能比以下内容更容易阅读:

export namespace Redux {
    export namespace Store {
        export interface Definition { ... }
    }
}

The external import is the same in both cases (e.g. import { Redux } from 'definitions/redux';), which I don't know if it's good practice or not, but I find it tidy! ^^

两种情况下的外部导入是相同的(例如import { Redux } from 'definitions/redux';),我不知道这是否是好的做法,但我觉得它很整洁!^^

It's important to keep in mind that adding an importor exportto your file will promote it to be a module, therefore the declarescope won't be at global level anymore.

重要的是要记住,向您的文件添加一个importorexport会将其提升为一个模块,因此declare范围将不再处于全局级别。

PS, there is a bug (issue 16671): if you use const enumin your declaration (I do that for the redux actions type) and you specified the transpileOnlyflag (create-react-app-typescriptpackage does, that's why I know), the enum won't be inlined! You may run in it, you may not, but it's useful to know beforehand!

PS,有一个错误(问题 16671):如果你const enum在你的声明中使用(我为 redux 操作类型这样做)并且你指定了transpileOnly标志(create-react-app-typescript包,这就是我知道的原因),枚举不会被内联!您可能会在其中运行,也可能不会,但是事先了解它很有用!