在TypeScript中声明关键字的目的

Ale*_*lls 20 typescript typescript2.0

declare关键字的目的是什么?

type Callback = (err: Error | String, data: Array<CalledBackData>) => void;
Run Code Online (Sandbox Code Playgroud)

declare type Callback = (err: Error | String, data:Array<CalledBackData>) => void;
Run Code Online (Sandbox Code Playgroud)

找不到解释declareTS中关键字用途的文档.

use*_*503 116

TL; 博士

declare 用于告诉编译器“这个东西(通常是一个变量)已经存在,因此可以被其他代码引用,也不需要将此语句编译成任何 JavaScript”。

常见用例:

您将网页的引用添加到编译器一无所知的 JavaScript 文件中。也许它是来自其他域的脚本,例如“foo.com”。评估时,脚本将使用一些有用的 API 方法创建一个对象,并将其分配给全局范围内的标识符“fooSdk”。

您希望您的 TypeScript 代码能够调用,fooSdk.doSomething()但由于您的编译器不知道此变量存在,您将收到编译错误。

然后使用declare关键字作为告诉编译器“相信我,这个变量存在并具有这种类型”的一种方式。编译器将使用此语句静态检查其他代码,但不会将其编译为输出中的任何 JavaScript。

declare const fooSdk = { doSomething: () => boolean }
Run Code Online (Sandbox Code Playgroud)

同样,您可以将 declare 关键字添加到类属性,以告诉编译器不要发出任何会创建此属性的代码,假设您有自己的代码来创建它,而编译器不知道或不理解.

您的具体示例有所不同,因为您声明的是类型,而不是变量,类型已经无法编译为任何 JavaScript。我不知道是否有任何理由声明一个类型。

  • @fires3as0n 我测试并发现了适用于当前版本 Typescript 的不同语法。添加到答案。 (8认同)
  • `declare const fooSdk = { doSomething: () =&gt; boolean }` 给出 **环境上下文中的 'const' 初始值设定项必须是字符串或数字文字或文字枚举引用。** 和 **'boolean' 仅引用一种类型,但在这里被用作值**错误,这个答案如何获得如此高的评价? (3认同)
  • 您能添加打字稿文档的链接吗?这几乎是一个很好的答案,并且通过一些链接来验证这些陈述将成为一个很好的答案。 (2认同)

sha*_* gh 21

考虑以下场景:您有一个 Typescript 项目。然后,无论出于何种原因,您决定用 JavaScript 编写一个模块,并在 Typescript 代码中使用它。

\n
// getMyName.js\nmodule.exports = function getMyName(name) {\n    return name;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后将其导入到打字稿代码中

\n
// myCode.ts\nimport getMyName from 'getMyName'; //getMyName is a JS module not typescript\n
Run Code Online (Sandbox Code Playgroud)\n

导入 JS 模块时(allowJs编译器选项应设置为false否则,JS 文件将在没有任何类型定义的情况下解析),Typescript 的编译器抱怨该模块根本不是一个模块!

\n

Could not find a declaration file for module '/absolute/path/to/getMyName.ts'

\n

这是因为 Typescript 本身不会\xe2\x80\x99 解析为 JS 代码。为了避免这个问题,我们应该filename.d.ts为 JS 模块提供类型定义 ()。为此,您可以使用declareexport

\n
// getMyName.d.ts\ndeclare function getMyName(name: string): string;\n\nexport default getMyName;\n
Run Code Online (Sandbox Code Playgroud)\n

之后,当我们导入 JS 模块时,TypeScript 不会抱怨任何事情,因为它现在可以访问类型。

\n

  • @AlexanderMills 是的,你是对的。编辑。 (3认同)
  • `import getMyName from 'getMyName';` 是 `default` 导出,也许你的意思是 `import {getMyName} from 'getMyName'`; (2认同)

cbd*_*per 13

来自打字稿文档:

Typescript - 使用其他 JavaScript 库

为了描述不是用 TypeScript 编写的库的形状,我们需要声明库公开的 API。因为大多数 JavaScript 库只公开几个顶级对象,所以命名空间是表示它们的好方法。

我们将没有定义实现的声明称为“环境”。通常这些定义在 .d.ts 文件中。如果您熟悉 C/C++,您可以将它们视为 .h 文件。让我们看几个例子。

环境命名空间

流行的库 D3 在名为 d3 的全局对象中定义其功能。因为这个库是通过标签(而不是模块加载器)加载的,它的声明使用命名空间来定义它的形状。为了让 TypeScript 编译器看到这个形状,我们使用了一个环境命名空间声明。例如,我们可以按如下方式开始编写它:

D3.d.ts(简化摘录)

declare namespace D3 {
    export interface Selectors {
        select: {
            (selector: string): Selection;
            (element: EventTarget): Selection;
        };
    }
    // (...)
}
Run Code Online (Sandbox Code Playgroud)


Sea*_*ley 10

这是一个真实的例子。

我有一个使用Webpack Hot Middleware的TypeScript React应用程序。Webpack中间件不是用TypeScript编写的,而是老式的JavaScript。因此,它没有打字稿编译器可以检查的类型声明。

因此,当我运行代码时,moduleWebpack Hot Middleware中的对象确实存在,并且即使它是老式的JavaScript,也隐藏在我新的TypeScript React应用中的某个地方,我也可以console.log它。

module对象还具有键,例如'module.hot',并且这些键可以具有值,但是VSCode中的TypeScript设计时编译器至少在其下方绘制了一个红色的波浪形 property 'hot' does not exist

但我说确实存在。

为了使TypeScript编译器同意,像下面这样声明

declare let module: any

现有module对象现在的类型为any,这使TypeScript编译器现在感到高兴,红色混乱地消失了,现在我可以继续编译并编写突破性的代码,这将改变世界。

另外,如果删除关键字declare并仅编写let module: any,它将不会编译为that 'module' already exists。所以我想这就是环境的意思。

  • `declare` 为已经存在的变量指定一种类型,而不是声明一个新变量。 (99认同)
  • 这是否像 C 语言的 **extern** 关键字一样,用于声明源代码之外的内容,并且编译器无法访问它?只有链接器稍后才能链接它们。因此 extern 将启用代码编译,否则会产生错误 (8认同)

小智 6

在编写任何实现代码之前,您可以使用声明告诉编译器有关类型的信息,TypeScript 会很高兴。

declare function foo(name: string): string
Run Code Online (Sandbox Code Playgroud)

  • 不包含任何有意义的含义。 (4认同)

Sch*_*eme 5

我从谷歌得到的第一个结果表明:

declare关键字用于环境声明,您可以在其中定义可能不是源自TypeScript文件的变量.

http://blogs.microsoft.co.il/gilf/2013/07/22/quick-tip-typescript-declare-keyword/

  • 我实际上还是不知道这意味着什么 (5认同)
  • 这是一个很差的答案。不要简单地链接到外部资源,任何人都可以做到。 (5认同)