为什么在语句中需要declare ?

export declare class Actions {
    ...
}

找到了我要找的东西

Declare vs. var

Var创建了一个新变量。declare用于告诉TypeScript该变量已在其他地方创建。如果使用declare,生成的JavaScript中不会添加任何内容——这只是给编译器的一个提示。

例如,如果你使用一个定义了var externalModule的外部脚本,你可以使用declare var externalModule来提示TypeScript编译器externalModule已经设置好了


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

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

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.


因此,在理解了“declare”关键字之后,回到找到该关键字的地方

export declare class Action{
...
}

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


在这个特定的情况下,declare关键字:

export declare class Actions {
    ...
}

... 显然是无用的,我认为TypeScript应该考虑使这个错误(我不知道是否有隐藏的原因)。如果你声明了一个类,你就永远不需要导入它。如果你导出一个类希望别人导入它,你不需要声明它。因为您声明了这个类,根据定义,这个类应该是可用的,而不需要导入它。但是当导出声明一个类时就不是这样了。您需要导入它才能使用。

博士TL;

export declare class Actions {
    ...
}

declare class Actions {
    ...
}

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

导入/导出是使用模块的正确方式,所有东西都需要手动导入(我觉得有点乏味),要么是逻辑,要么是定义。

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

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

这可能比以下更容易读懂:

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

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

重要的是要记住,向文件添加导入或导出会将其提升为模块,因此声明范围将不再是全局级别的。

PS,有一个错误(问题16671):如果你在你的声明中使用const enum(我这样做的redux动作类型),你指定了transpileOnly标志(create-react-app-typescript包做,这就是为什么我知道),enum不会内联!你可能会跑进去,也可能不会,但事先知道是很有用的!


在typescript中声明:

typescript中的declare关键字非常有用,它可以告诉typescript编译器某个声明是在其他地方定义的(写在外部javascript文件中或运行时环境的一部分)。

假设我们有一个变量foo声明在别的地方。当我们尝试引用变量时,typescript编译器将抛出一个错误:

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

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

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

这有以下后果:

当foo实际上没有在其他任何地方声明,并且我们尝试使用该变量时,可能会发生运行时错误。因此,只有在知道变量此时可用时才使用declare关键字。 因为我们知道类型,我们(潜在地)可以访问我们的IDE智能感知。 因为我们知道类型,所以typescript编译器可以在编译时检查类型,并在某些情况下警告我们使用了错误的类型。