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

bor*_*net 138 typescript

为什么我们需要declare在声明中?

export declare class Actions {
    ...
}
Run Code Online (Sandbox Code Playgroud)

bor*_*net 176

找到了我要找的东西:

声明与变量

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

例如,如果您使用定义外部脚本var externalModule,你会用declare var externalModule暗示来的打字稿编译器externalModule已经建立


Ter*_*nce 82

要理解这一点,您必须先了解"declare"关键字.

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

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

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

declare var myLibrary;
Run Code Online (Sandbox Code Playgroud)

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

var myLibrary: any;
Run Code Online (Sandbox Code Playgroud)

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


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

export declare class Action{
...
}
Run Code Online (Sandbox Code Playgroud)

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

  • “两个代码示例都会产生相同的 JavaScript 输出”,这是不正确的: `declare var myLibrary` 将转换为空:http://www.typescriptlang.org/play/#code/CYUwxgNghgTiAEEQBd4DMD2GBcBnZMAlgHYDmA3AFBKoBGs8AvPAORQtWWVA (2认同)

Wil*_*een 19

declare 在打字稿中:

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

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

foo = 'random'; // Error: 'foo' is not defined
Run Code Online (Sandbox Code Playgroud)

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

declare var foo: string;
foo = 'random';  // no error anymore
Run Code Online (Sandbox Code Playgroud)

这具有以下后果:

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


And*_*ena 12

在这种特定情况下,define关键字是:

export declare class Actions {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

TL; DR

export declare class Actions {
    ...
}
Run Code Online (Sandbox Code Playgroud)

是相同的

declare class Actions {
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为它们不一样,前者需要与“import”一起使用,后者则不需要 (3认同)

pie*_*tom 7

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

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

作为实际用例,export declare可以避免导出所有子元素,例如:

export declare namespace Redux {
    namespace Store {
        interface Definition { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

export namespace Redux {
    export namespace Store {
        export interface Definition { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

请务必记住,将import或添加export到文件中会将其提升为模块,因此declare作用域将不再处于全局级别。

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