【发布时间】:2016-05-03 09:05:42
【问题描述】:
为什么我们需要在语句中使用declare?
export declare class Actions {
...
}
【问题讨论】:
标签: typescript
为什么我们需要在语句中使用declare?
export declare class Actions {
...
}
【问题讨论】:
标签: typescript
declare 在打字稿中:typescript 中的 declare 关键字有助于告诉 typescript 编译器 声明 是在其他地方定义的(在外部 javascript 文件或运行时环境的一部分中编写的地方)。
假设我们在其他地方声明了一个名为 foo 的变量。当我们尝试引用该变量时,打字稿编译器会抛出一个错误:
foo = 'random'; // Error: 'foo' is not defined
我们可以使用declare 关键字来解决这个问题:
declare var foo: string;
foo = 'random'; // no error anymore
这会产生以下后果:
foo 实际上没有在其他任何地方声明,并且我们尝试使用该变量时,可能会发生运行时错误。因此,仅当您知道该变量此时可用时才使用 declare 关键字。【讨论】:
在这种特定情况下的 declare 关键字:
export declare class Actions {
...
}
... 显然没用,我认为 TypeScript 应该考虑将其作为错误(我不知道是否有隐藏的原因)。如果你声明一个类,你永远不需要导入它。如果您导出一个期望有人导入它的类,则不需要声明它。并且因为您正在声明此类,根据定义,此类应该无需导入即可使用。但是,当您export declare 一个类时,情况并非如此。您需要导入才能使用。
TL;DR
export declare class Actions {
...
}
和
一样declare class Actions {
...
}
【讨论】:
import一起使用,后者不需要
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';),我不知道这是否是好的做法,但我觉得它很整洁! ^^
请务必记住,向文件添加 import 或 export 会将其提升为模块,因此 declare 范围将不再处于全局级别。
PS,有一个错误(issue 16671):如果您在声明中使用const enum(我为redux 操作类型这样做)并且您指定了transpileOnly 标志(create-react- app-typescript 包确实如此,这就是我知道的原因),枚举不会被内联!你可以跑进去,也可以不跑,但提前知道很有用!
【讨论】:
export namespace 是 not a good idea 并添加 needless namespacing。关于export declare,看看André Pena 的回答。
要理解这一点,首先要理解“declare”关键字。
这是来自Gil Fink's Blog的一个很好的解释:
TypeScript 声明关键字用于声明可能不是源自 TypeScript 文件的变量。
例如,假设我们有一个名为 myLibrary 的库,它没有 TypeScript 声明文件,并且在全局命名空间中有一个名为 myLibrary 的命名空间。如果您想在 TypeScript 代码中使用该库,可以使用以下代码:
declare var myLibrary;TypeScript 运行时将赋予 myLibrary 变量的类型是 any 类型。这里的问题是您在设计时不会为该变量提供 Intellisense,但您将能够在代码中使用该库。在不使用 declare 关键字的情况下具有相同行为的另一种选择是仅使用具有 any 类型的变量:
var myLibrary: any;两个代码示例将产生相同的 JavaScript 输出,但 declare 示例更具可读性并且表达了环境声明。
所以在你理解了“declare”关键字之后,回到你找到的地方
export declare class Action{
...
}
该类的真正实现可能在其他地方——可能是一个 .js 文件。
【讨论】:
declare var myLibrary 将转译为空:typescriptlang.org/play/#code/…
找到了我要找的东西:
声明与 var
var 创建一个新变量。 declare 用于告诉 TypeScript 该变量已在别处创建。如果您使用declare,则不会向生成的 JavaScript 添加任何内容 - 它只是对编译器的提示。
例如,如果您使用定义 var externalModule 的外部脚本,您将使用 declare var externalModule 向 TypeScript 编译器提示 externalModule 已设置
【讨论】:
externalModule 等等。 externalModule 在运行时未定义但其他一些变量未定义的原因可能是什么?