声明了类型,但我无法使用它。为什么?

时间:2017-05-15 07:25:46

标签: typescript

我正在使用this bson库和this声明。该库有一个方法serialize():Buffer,它返回Buffer。当我这样调用代码时:

let data:Buffer = this.serializer.serialize();

一切正常 - 我可以在调试器中看到data,检查其字段。

但是当我尝试直接创建Buffer的实例时:

let buf:Buffer = new Buffer(10);

我收到运行时错误 - ReferenceError: Buffer is not defined。为什么这样以及如何解决?

2 个答案:

答案 0 :(得分:1)

仅仅因为某些东西的打字并不意味着它在转换成JavaScript时必须存在。例如:

type Buffer = ArrayBuffer | Array<any>;

let foo: Buffer = [1, 2]; // OK

new Buffer(); // Error

(你可以test it

在您的情况下,打字文件说明serialize返回

  

@return {Buffer}根据浏览器支持的内容返回TypedArray或Array

答案 1 :(得分:1)

在typescript中定义名称时,可以在变量声明空间类型声明空间(或两者)中定义它们。

变量声明空间是所有Javascript事件发生的地方:所以当你let foo: Buffer = [1, 2];定义foo作为变量时,输出的Javascript代码也将包含foo

类型声明空间是所有类型相关的东西发生的地方,并且没有一个存活到Javascript。

如果定义class,它为变量声明空间和类型声明空间添加名称,但是如果定义interface,则只为类型声明空间添加名称。要实例化一个变量,你需要有一个你可以调用的构造函数,但如果你只有一个类型,那么你就无法使用它。

interface Buffer extends NodeBuffer { };

所以这第一个声明提供了类型信息。这意味着编译器和编辑器可以进行类型检查,并告诉您是否尝试访问不存在的属性。但这都在类型声明空间中,它不会向变量声明空间添加任何内容:输出Javascript中没有Buffer

declare var Buffer: {...}

这就是所谓的环境声明:它说某处有一些Javascript创建了一个名为Buffer的全局变量。如果您尝试使用Buffer,编译器会相信并且不会抱怨,但您有责任确保Javascript创建变量的任何内容都包含在您的页面中。

所以ReferenceError发生了,因为编译器承诺Buffer将在运行时出现,但是尚未包含创建Buffer变量的Javascript。

有关变量声明空间类型声明空间的更多说明,请参阅https://basarat.gitbooks.io/typescript/content/docs/project/declarationspaces.html

编辑:我根本不知道bson,但文档实际上并没有说您可以直接创建Buffer。因此,当你声称命名空间中应该有一个全局Buffer时,你可以成功地序列化的事实意味着它是错误的类型库。我认为它应该只是为您提供界面,如果你拥有的只是一个界面,你不能期望实例化。