2016-09-23 8 views
1

고궁 박물원 패키지 csv-parse는 API 같은 Node.js를 스트림을 구현TypeScript에서 Stream-like 인터페이스를 선언하는 방법은 무엇입니까?

const parser = parse(); 
parser.on('readable',() => { 
    let record: any; // <-- it should be string[] 
    while (record = parser.read()) { 
    output.push(record); 
    } 
}); 

type declaration은 다음과 같습니다

interface parse { 
    (options?: options): NodeJS.ReadWriteStream; 
} 

parse의 반환 형식이 string | Buffer을 반환하는 방법 read을 가지고 NodeJS.ReadWriteStream이다. 이 정의에 의해

interface ReadWriteStream extends ReadableStream, WritableStream { 
    // ... 
} 

interface ReadableStream extends EventEmitter { 
    read(size?: number): string | Buffer; 
    // ... 
} 

, I 형은 실제 string[]let record: any = parser.read() 변수를 정의 할 수있다.

내가 유형 정의 수정 시도 같은 CSV를-분석 : 타이프 라이터가 인터페이스 변경 방법의 반환 유형을 확장 할 수 없습니다 때문에

interface ParserStream extends NodeJS.ReadWriteStream { 
    read(size?: number): string[];  
} 

interface parse { 
    (options?: options): ParserStream; 
} 

그것은 작동하지 않습니다. 내가 생각할 수있는 어떤

같은 일반적인 유형 NodeJS 스트림을 변경하는 것입니다 :

interface GenericReadableStream <T> extends EventEmitter { 
    read(size?: number): T 
    // ... 
} 

interface ReadableStream extends GenericReadableStream <string | Buffer> {} 

은 그 때 나는 정의 할 수 있습니다 : 그것은 좋은 방법이 있다면

interface ParserStream extends GenericReadableStream <string[]> {} 

모르겠어요. 현재 Node.JS 유형 정의에 많은 영향을줍니다. 시작하기

답변

1

는 CsvParser 구현은 그렇게 string | Buffer 정말 CsvParser.read에 대한 좋은 반환 형식이 아닙니다, object mode에 스팀을 사용합니다.

다행히 TypeScript를 사용하면 인터페이스를 확장하고 메서드의 반환 유형을 any으로 변경할 수 있습니다. 그래서 당신은이 코드가

let record: string[]; 
while (record = parser.read()) { 

를 컴파일 할 수 있도록

interface CsvParser extends NodeJS.ReadWriteStream { 
     read(size?: number): any; 

csv-parse 유형 정의를 변경할 수 있습니다하지만이 너무 컴파일 때문에이 충분히 엄격하지 않다 :

let record: number[]; 
while (record = parser.read()) { 

는 그것을 허용하지 , 당신은 어떻게 든 read 반환 유형을 string[]으로 변경하는 인터페이스를 선언해야합니다.은 직접 ReadWriteStream으로 확장되는 인터페이스에서 수행 할 수 없습니다. 왜냐하면 string[]string | Buffer과 호환되지 않기 때문입니다. 그러나 중간 단계를 추가하는 경우 가능합니다. 즉, ReadWriteStream을 확장하고 read에 대한 반환 유형이 둘 다 호환되는 인터페이스가 가능합니다.

interface ObjectStream<T> extends NodeJS.ReadWriteStream { 
    read(size?: number): any & T; 
} 

그런 다음 당신이 CsvParser이 그것을 확장 할 수 있습니다 : 그것은 우리가 일반적인 매개 변수 T 사용할 수있는 any의 교차 타입과 원하는 유형이 될 수 있습니다

interface CsvParser extends ObjectStream<string[]> { 
    read(size?: number): string[]; 
} 

그 방법을, 당신은 여전히 ​​필요 csv-parser 유형 정의를 수정하되 노드 스트림에 대한 유형 정의를 변경할 필요가 없습니다.

참고 : 답의 첫 번째 시도는 @aleung 눈치로 아직 읽어 결과를 할당 할 수 있기 때문에,

interface CsvParser extends NodeJS.ReadWriteStream { 
     read(size?: number): any; 

다르지없는,

interface CsvParser extends NodeJS.ReadWriteStream { 
     read(size?: number): any & string[]; 

했다 어떤 유형의 변수.

+1

필자는 TypeScript 2.0.3에서 테스트를 마쳤습니다. 'any'와'string []'의 상호 작용은'any'입니다. 따라서'number [] '에 여전히 할당 할 수 있습니다. – aleung

+0

오 예 답변을 단순화하고 확인하지 않았습니다. ReadWriteStream과 CsvParser 사이에 하나의 중간 인터페이스가 필요합니다.이 인터페이스에서'any & string []'을 반환하기 위해'read'를 재정의하면 CsvParser에서'string []'만 반환하도록 재정의 할 수 있습니다. 나는 다시 점검하고 대답을 업데이트 할 것이다. – artem

+0

답변을 업데이트했습니다. 이제는 제대로 작동 할 것입니다. – artem

관련 문제