Node.js 使用TypeScript正确扩展stream.Transform类
我有以下代码:Node.js 使用TypeScript正确扩展stream.Transform类,node.js,typescript,tsc,typescript3.0,Node.js,Typescript,Tsc,Typescript3.0,我有以下代码: import * as stream from 'stream'; export class JSONParser extends stream.Transform { lastLineData = ''; objectMode = true; constructor() { super(); } transform(chunk, encoding, cb) { let data = String(chunk); i
import * as stream from 'stream';
export class JSONParser extends stream.Transform {
lastLineData = '';
objectMode = true;
constructor() {
super();
}
transform(chunk, encoding, cb) {
let data = String(chunk);
if (this.lastLineData) {
data = this.lastLineData + data;
}
let lines = data.split('\n');
this.lastLineData = lines.splice(lines.length - 1, 1)[0];
lines.forEach(l => {
try {
// l might be an empty string; ignore if so
l && this.push(JSON.parse(l));
}
catch (err) {
// noop
}
});
cb();
}
flush(cb) {
if (this.lastLineData) {
try {
this.push(JSON.parse(this.lastLineData));
}
catch (err) {
// noop
}
}
this.lastLineData = '';
cb();
}
}
问题是TS类型不能识别(原型)方法。我是否错误地扩展了Transform类
问题是:
请注意,这是正确的:
import * as stream from 'stream';
//////////////////////////////////////////////////
export interface IParsedObject {
[index: string]: any
}
export const createParser = function () {
let lastLineData = '';
return new stream.Transform({
objectMode: true,
transform(chunk: any, encoding: string, cb: Function) {
let data = String(chunk);
if (lastLineData) {
data = lastLineData + data;
}
let lines = data.split('\n');
lastLineData = lines.splice(lines.length - 1, 1)[0];
lines.forEach(l => {
try {
// l might be an empty string; ignore if so
l && this.push(JSON.parse(l));
}
catch (err) {
// noop
}
});
cb();
},
flush(cb: Function) {
if (lastLineData) {
try {
this.push(JSON.parse(lastLineData));
}
catch (err) {
// noop
}
}
lastLineData = '';
cb();
}
});
};
但是上面的类似乎工作不一样。好的,现在它似乎工作了,我必须将构造函数选项传递给
super()
,所以它变成super({objectMode:true})
剩下的唯一问题是我应该实现
\u flush()
还是flush()
,我不确定…我现在实现了这两个…在您的屏幕截图中,您试图扩展Transform
类,但您没有实现正确的方法,您应该实现Transform.\u Transform(区块,编码,回调)
,则typescript将自动推断所需的类型。由于转换上不存在转换类型typescript没有用于推断的类型,因此编译器生成警告
在代码示例中,您选择使用“简化”Transform
构造函数。构造函数采用一组选项,允许您定义必要的转换方法,而无需显式扩展类。这些选项选择非下划线前缀命名约定,但在扩展类时,它们与下划线前缀方法等效。因为您使用了方法的正确名称此处可以推断类型
Transform
API调用了三种方法的实现,下面对这些方法进行了概述
有两种方法可以实现转换
流:
扩展转换
类
使用转换
构造函数
选项
概述了这两种方法(包括在ES6之前的环境中扩展类的示例)
在实现转换时
流只能实现一种方法:
transform.\u转换(块、编码、回调)
其他两种方法是可选的,如果用例需要,可以实现:
transform.\u刷新(回调)
可写。_final(回调)
我已经在下面概述了文档化的Transform
方法,突出了一些可能感兴趣的领域
应用程序代码不能直接调用此函数。它
应该由子类实现,并由内部
仅可读类方法。
在某些情况下,变换操作可能需要发出额外的
流末尾的数据位。例如,zlib压缩
流将存储一定数量的内部状态,用于优化
压缩输出。但是,当流结束时,额外的
需要刷新数据,以便完成压缩数据
自定义转换实现可以实现转换。_flush()
方法。当没有更多的写入数据时,将调用此方法
已消耗,但在发出“结束”事件之前,发出结束的信号
可读流
在transform._flush()实现中,可读的.push()
方法可能被调用零次或多次(视情况而定)
函数必须在刷新操作完成时调用
transform.\u flush()方法的前缀为下划线,因为
它是定义它的类的内部,永远不应该是
由用户程序直接调用。
应用程序代码不能直接调用此函数。它
应该由子类实现,并由内部
仅可读类方法。
所有转换流实现都必须提供一个_Transform()
方法接受输入并生成输出。转换。_transform()
实现处理正在写入的字节,计算输出,
然后使用
readable.push()方法
可以零次或多次调用transform.push()方法来
从单个输入块生成输出,具体取决于要输入的数据量
将被输出为块的结果
任何给定的数据块都可能不会生成任何输出
输入数据
仅当当前块为空时,才能调用回调函数
已完全使用。传递给回调的第一个参数必须为
如果在处理输入或输出时发生错误,则为错误对象
否则为null。如果将第二个参数传递给回调,则
将转发到可读的.push()方法
以下是等效的:
转换。_transform()方法的前缀是
使用下划线,因为它是定义
用户程序不应直接调用它。
transform.\u transform()从不并行调用;流实现
一个队列机制,要接收下一个块,回调必须是
以同步或异步方式调用
不能直接调用_final()方法。它可以实现
由子类调用,如果是,将由内部可写
仅类方法。
此可选函数将在流关闭之前调用,
延迟“完成”事件直到调用回调。这很有用
在流结束前关闭资源或写入缓冲数据
流API有详尽的文档。您可以找到实现所需的方法,还可以找到有关实现Transform
streams的具体细节。@JakeHolzinger不够全面,是吗
export class JSONParser extends stream.Transform {
lastLineData = '';
constructor() {
super({objectMode: true});
}
_transform(chunk: any, encoding: string, cb: Function) {
let data = String(chunk);
if (this.lastLineData) {
data = this.lastLineData + data;
}
let lines = data.split('\n');
this.lastLineData = lines.splice(lines.length - 1, 1)[0];
lines.forEach(l => {
try {
// l might be an empty string; ignore if so
l && this.push(JSON.parse(l));
}
catch (err) {
// noop
}
});
cb();
}
flush(cb: Function) {
if (this.lastLineData) {
try {
this.push(JSON.parse(this.lastLineData));
}
catch (err) {
// noop
}
}
this.lastLineData = '';
cb();
}
_flush(cb: Function) {
if (this.lastLineData) {
try {
this.push(JSON.parse(this.lastLineData));
}
catch (err) {
// noop
}
}
this.lastLineData = '';
cb();
}
}
transform.prototype._transform = function(data, encoding, callback) {
this.push(data);
callback();
};
transform.prototype._transform = function(data, encoding, callback) {
callback(null, data);
};