在'export declare class Actions'中'声明'做了什么?

时间:2016-01-26 17:26:29

标签: typescript

为什么我们需要声明中的export declare class Actions { ... }

1.c:3:7: error: use of undeclared identifier 'x'
    if ( x== y) { 
         ^

5 个答案:

答案 0 :(得分:134)

找到了我要找的东西:

声明与var

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

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

答案 1 :(得分:69)

要理解这一点,你必须先了解"声明"关键字。

以下是Gil Fink's Blog的一个很好的解释:

  

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

  

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

declare var myLibrary;
     

TypeScript运行时将为myLibrary变量提供的类型是any类型。这里的问题是您在设计时不会对该变量进行Intellisense,但您可以在代码中使用该库。在不使用declare关键字的情况下具有相同行为的另一个选项是使用任何类型的变量:

var myLibrary: any;
     

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

所以,在你理解了"声明"关键字,返回到找到

的地方
export declare class Action{
...
}

该类的真正实现可能在其他地方 - 也许是.js文件。

答案 2 :(得分:9)

declare(打字稿中):

打字稿中的declare关键字可用于告诉打字稿编译器在其他地方(在外部javascript文件或运行时环境的一部分中编写)定义了声明

假设我们在另一个地方声明了一个名为foo的变量。然后,当我们尝试引用变量时,打字稿编译器将抛出错误:

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

我们可以使用declare关键字解决此问题:

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

这具有以下后果:

  • foo实际上未在其他任何地方声明时,我们尝试使用该变量,可能会发生运行时错误。因此,仅当您知道变量此时可用时,才使用declare关键字。
  • 因为我们知道我们可以(可能)访问我们的IDE Intellisense 的类型。
  • 因为我们知道打字稿编译器可以在编译时检查类型的类型,并且可以在某些情况下使用错误的类型向我们发出警告。

答案 3 :(得分:7)

此特定情况下的声明关键字:

export declare class Actions {
    ...
}

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

<强> TL; DR

export declare class Actions {
    ...
}

相同
export class Actions {
    ...
}

答案 4 :(得分:6)

declare-无需任何导入或导出关键字-定义由TypeScript自动选择的声明文件,这是将键入添加到旧版模块(无TypeScript定义的npm已安装软件包)的有用功能。

import / export是使用模块的正确方法,所有内容都需要手动导入(我觉得有点乏味),无论是逻辑上还是定义上。

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

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

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

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

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

请务必记住,在文件中添加importexport会将其提升为模块,因此declare范围将不再处于全局级别

PS,有一个错误(issue 16671):如果您在声明中使用const enum(我对redux动作类型进行此操作),并且您指定了transpileOnly标志(< em> create-react-app-typescript 包确实有,这就是我知道的原因),该枚举不会被内联!您可以运行它,也可以不运行它,但是事前了解很有用!

相关问题