在TypeScript中使用`declare`关键字的最简单的例子是什么?

时间:2019-04-26 14:11:13

标签: typescript

我已经阅读了TypeScript中的文档(即this)和一些有关declare关键字的博客文章,但我仍然不理解。我想要的是一个最简单用法的清晰示例。

这是我最初想出的最简单的例子(可能是错误的)的推理方法:

有一个.js文件可以导出某些内容(因为它是纯JS,所以未键入)。

无论导出的.ts文件如何,都导入.js文件。

要让我看到TS显示可以通过使用declare来解决的错误,需要导出和导入哪些内容(一个对象或一个函数?)?

2 个答案:

答案 0 :(得分:2)

您的示例是正确的。例如,您正在使用用普通javascript编写的节点模块(没有可用的类型),因此tscompiler会注意到这一点(因为它搜索通常在节点模块中或其他@typings/package中的类型)。

不过,您可以通过告诉tsconfig.json中的tscompiler来查看文件xyz.d.ts中的键入内容来自己提供这些键入内容,例如

tsconfig.json
{
  "files": [
    "typings/index.d.ts"
  ]
}

index.d.ts是收集所有看起来像这样的自定义键入内容的地方

index.d.ts
/// <reference path="custom-typings.d.ts" />

custom-typings.d.ts中有实际的键入内容。这就是declare关键字的作用

custom-typings.d.ts
declare module "the-untyped-node-module-name" {
    export default class TheNodeModuleClass { 
        static showNotification(string: any): void;
    }
}

现在,打字稿编译器知道TheNodeModuleClass中有一个the-untyped-node-module-name,它具有静态功能showNotification

有关更多信息,See Typscript Modules


这是关键字declare的一种用例。当然还有更多类似declare vardeclare functiondeclare class之类的东西。

答案 1 :(得分:0)

上面的MuratKaragöz答案指向了正确的方向,该答案将提供实际的代码,并提供一个最小的示例,说明我们将在何处使用declare

Here是一个非常简单的npm模块:只有一个index.js文件可以导出带有一种方法的对象。这里没有类型声明,因为它只是JS。

const item = {
    price: 5,
    name: 'item1',
};

export const MyModuleObject = { method: () => item };

Here是一个非常简单的TypeScript npm项目,具有一个依赖项:上面链接的JS项目。因此,后者是导入的npm模块,无需输入任何内容。这是TS项目中的index.ts文件:

/// <reference path="index.d.ts"/>

import { MyModuleObject } from 'npmModule';

import { LocalModuleObject } from './module';

// Without the "reference path" line, TS complains in line 3 that it could not find a declaration file for 'npmModule'.
// In this case, the import has type any, so TS does not complain about the call below to an inexistent method.
// When we uncomment line 1, we get a TS error on line 8: property 'test' does not exist on type { method: ... }
MyModuleObject.test();


// TS complains that test does not exist on type { method: ... }
// Here we did not need to have a `declare` statement in a type definitions file for TS to know this because here TS is
// using contextual typing:
LocalModuleObject.test();

下面是index.d.ts的代码:

declare module "npmModule" {
    export const Item: {
        price: number,
        name: string
    }

    export const MyModuleObject: {
        method: () => Item
    }
}

还有./module的代码:

export const LocalModuleObject = { method: () => 10 };

这是一个为什么使用声明的示例 -我将其放在index.ts的注释中,但让我用更多的词来解释。 index.ts正在从外部模块(node_modules中的一个)导入对象,并从本地模块(./module.js)导入另一个对象。这两个模块都使用一个名为method的方法导出对象。在index.ts中,我在每个这些对象上调用了一个不存在的方法test

TS在导入本地模块时使用上下文类型,因此它知道对象上不存在test。在外部模块中导入对象时不会发生这种情况:此导入的类型为any。因此,TS不会抱怨对不存在的方法test的调用。但是,它确实抱怨外部模块没有任何类型,因此这暗示着正在使用隐式any

我们可以通过定义一个index.d.ts来纠正后一种抱怨,该declare module为外部库提供类型。这就是使用npmModule的地方:它声明模块npmModule导出的内容; index.ts是外部导入。在/// <reference path="index.d.ts"/>中,我们必须添加行private async void UploadImage() { var token = Application.Current.Properties["token"].ToString(); var multiForm = new MultipartFormDataContent(); var imagFile = _mediaFile.AlbumPath; var upfilebytes = File.ReadAllBytes(imagFile); ByteArrayContent baContent = new ByteArrayContent(upfilebytes); multiForm.Add(new StringContent("1"), "x"); multiForm.Add(new StringContent("100"), "y"); multiForm.Add(new StringContent("100"), "width"); multiForm.Add(new StringContent("100"), "height"); multiForm.Add(baContent, "file", Path.GetFileName(_mediaFile.AlbumPath)); var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6" + "IkpXVCJ9.eyJYwZi05MjhhLTRiZjctYjZkNi0wY2U1ODRkOGRjZmQiLCJ1bmlxdWVfbmFtZ" + "SI6IjIwZDA0MDY3LTU3YzYtNGY2MC04ZDI5LTg1NzkxMmFmOWI2MSIsImNsdCI6ImVuLUdCIiwidHoiOiJ" + "XLiBFdXJvcGUgU3RhbmRhtZSIsIm5iZiI6MTU1NjQ3NTMyNCwiZXhwIjoxNTU2NDgyNTI0LCJpY" + "XQiOjE1NTY0NzUzMjQsImlzcyI6Imh0dHBzOi8vYXBpLnZpYS5zb2Z0d2FyZSIsImF1ZCI6Imh0dHBz" + "Oi8vd3d3LnZpYS5zb2Z0d2FyZSJ9.z5rghA338FDAtoInFYugMgwIirrdl9CrsGKhS8ceoFI"); var response = await client.PostAsync(utils.Settings.BaseUrl + "/auth/Users/ChangeAvatar", multiForm); Debug.WriteLine("--> * "+response.Content.ReadAsStreamAsync().Result); Debug.WriteLine("response --> * "+_mediaFile.AlbumPath); Debug.WriteLine("--> * " + response); } ,以便TS知道在哪里查找类型。