From 37bcddb3e7247ada9dceca821eaaecfbc5cbde4f Mon Sep 17 00:00:00 2001 From: Yu Shimura Date: Sat, 1 Dec 2018 11:55:06 +0900 Subject: [PATCH] Parsed result now statically typed --- types/binary-parser/binary-parser-tests.ts | 25 +++ types/binary-parser/index.d.ts | 187 ++++++++++++--------- 2 files changed, 133 insertions(+), 79 deletions(-) diff --git a/types/binary-parser/binary-parser-tests.ts b/types/binary-parser/binary-parser-tests.ts index d0d09e5ef7..9eca89211c 100644 --- a/types/binary-parser/binary-parser-tests.ts +++ b/types/binary-parser/binary-parser-tests.ts @@ -93,3 +93,28 @@ const parser5 = new Parser() length: '4', formatter: (arr) => { } }); + +const parser6 = new Parser() + .nest("nested", { + type: new Parser() + .array("points", { + type: new Parser() + .uint8("x") + .uint8("y"), + length: 2 + }) + }) + .choice("optional", { + tag: "nested.points[0].x", + choices: { + 1: new Parser() + .uint8("number") + } + }); + +const result = parser6.parse(Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05])); + +// See the inferred static types on the IntelliSense. +result.nested.points[0].x; +result.nested.points[1].y; +result.optional.number; diff --git a/types/binary-parser/index.d.ts b/types/binary-parser/index.d.ts index 657996bd8d..b16f433e55 100644 --- a/types/binary-parser/index.d.ts +++ b/types/binary-parser/index.d.ts @@ -1,88 +1,117 @@ // Type definitions for binary-parser 1.3 // Project: https://github.com/keichi/binary-parser -// Definitions by: Benjamin Riggs , Dolan Miu +// Definitions by: Benjamin Riggs , +// Dolan Miu , +// Yu Shimura // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 /// -export interface Parser { - parse(buffer: Buffer, callback?: (err?: Error, result?: any) => void): Parser.Parsed; +export interface Parser { + parse(buffer: Buffer, callback?: (err?: Error, result?: any) => void): Parser.Parsed; create(constructorFunction: ObjectConstructor): Parser; - int8(name: string, options?: Parser.Options): Parser; - uint8(name: string, options?: Parser.Options): Parser; + int8(name: N, options?: Parser.Options): Parser.Next; + uint8(name: N, options?: Parser.Options): Parser.Next; - int16(name: string, options?: Parser.Options): Parser; - uint16(name: string, options?: Parser.Options): Parser; - int16le(name: string, options?: Parser.Options): Parser; - int16be(name: string, options?: Parser.Options): Parser; - uint16le(name: string, options?: Parser.Options): Parser; - uint16be(name: string, options?: Parser.Options): Parser; + int16(name: N, options?: Parser.Options): Parser.Next; + uint16(name: N, options?: Parser.Options): Parser.Next; + int16le(name: N, options?: Parser.Options): Parser.Next; + int16be(name: N, options?: Parser.Options): Parser.Next; + uint16le(name: N, options?: Parser.Options): Parser.Next; + uint16be(name: N, options?: Parser.Options): Parser.Next; - int32(name: string, options?: Parser.Options): Parser; - uint32(name: string, options?: Parser.Options): Parser; - int32le(name: string, options?: Parser.Options): Parser; - int32be(name: string, options?: Parser.Options): Parser; - uint32le(name: string, options?: Parser.Options): Parser; - uint32be(name: string, options?: Parser.Options): Parser; + int32(name: N, options?: Parser.Options): Parser.Next; + uint32(name: N, options?: Parser.Options): Parser.Next; + int32le(name: N, options?: Parser.Options): Parser.Next; + int32be(name: N, options?: Parser.Options): Parser.Next; + uint32le(name: N, options?: Parser.Options): Parser.Next; + uint32be(name: N, options?: Parser.Options): Parser.Next; - bit1(name: string, options?: Parser.Options): Parser; - bit2(name: string, options?: Parser.Options): Parser; - bit3(name: string, options?: Parser.Options): Parser; - bit4(name: string, options?: Parser.Options): Parser; - bit5(name: string, options?: Parser.Options): Parser; - bit6(name: string, options?: Parser.Options): Parser; - bit7(name: string, options?: Parser.Options): Parser; - bit8(name: string, options?: Parser.Options): Parser; - bit9(name: string, options?: Parser.Options): Parser; - bit10(name: string, options?: Parser.Options): Parser; - bit11(name: string, options?: Parser.Options): Parser; - bit12(name: string, options?: Parser.Options): Parser; - bit13(name: string, options?: Parser.Options): Parser; - bit14(name: string, options?: Parser.Options): Parser; - bit15(name: string, options?: Parser.Options): Parser; - bit16(name: string, options?: Parser.Options): Parser; - bit17(name: string, options?: Parser.Options): Parser; - bit18(name: string, options?: Parser.Options): Parser; - bit19(name: string, options?: Parser.Options): Parser; - bit20(name: string, options?: Parser.Options): Parser; - bit21(name: string, options?: Parser.Options): Parser; - bit22(name: string, options?: Parser.Options): Parser; - bit23(name: string, options?: Parser.Options): Parser; - bit24(name: string, options?: Parser.Options): Parser; - bit25(name: string, options?: Parser.Options): Parser; - bit26(name: string, options?: Parser.Options): Parser; - bit27(name: string, options?: Parser.Options): Parser; - bit28(name: string, options?: Parser.Options): Parser; - bit29(name: string, options?: Parser.Options): Parser; - bit30(name: string, options?: Parser.Options): Parser; - bit31(name: string, options?: Parser.Options): Parser; - bit32(name: string, options?: Parser.Options): Parser; + bit1(name: N, options?: Parser.Options): Parser.Next; + bit2(name: N, options?: Parser.Options): Parser.Next; + bit3(name: N, options?: Parser.Options): Parser.Next; + bit4(name: N, options?: Parser.Options): Parser.Next; + bit5(name: N, options?: Parser.Options): Parser.Next; + bit6(name: N, options?: Parser.Options): Parser.Next; + bit7(name: N, options?: Parser.Options): Parser.Next; + bit8(name: N, options?: Parser.Options): Parser.Next; + bit9(name: N, options?: Parser.Options): Parser.Next; + bit10(name: N, options?: Parser.Options): Parser.Next; + bit11(name: N, options?: Parser.Options): Parser.Next; + bit12(name: N, options?: Parser.Options): Parser.Next; + bit13(name: N, options?: Parser.Options): Parser.Next; + bit14(name: N, options?: Parser.Options): Parser.Next; + bit15(name: N, options?: Parser.Options): Parser.Next; + bit16(name: N, options?: Parser.Options): Parser.Next; + bit17(name: N, options?: Parser.Options): Parser.Next; + bit18(name: N, options?: Parser.Options): Parser.Next; + bit19(name: N, options?: Parser.Options): Parser.Next; + bit20(name: N, options?: Parser.Options): Parser.Next; + bit21(name: N, options?: Parser.Options): Parser.Next; + bit22(name: N, options?: Parser.Options): Parser.Next; + bit23(name: N, options?: Parser.Options): Parser.Next; + bit24(name: N, options?: Parser.Options): Parser.Next; + bit25(name: N, options?: Parser.Options): Parser.Next; + bit26(name: N, options?: Parser.Options): Parser.Next; + bit27(name: N, options?: Parser.Options): Parser.Next; + bit28(name: N, options?: Parser.Options): Parser.Next; + bit29(name: N, options?: Parser.Options): Parser.Next; + bit30(name: N, options?: Parser.Options): Parser.Next; + bit31(name: N, options?: Parser.Options): Parser.Next; + bit32(name: N, options?: Parser.Options): Parser.Next; - float(name: string, options?: Parser.Options): Parser; - floatle(name: string, options?: Parser.Options): Parser; - floatbe(name: string, options?: Parser.Options): Parser; + float(name: N, options?: Parser.Options): Parser.Next; + floatle(name: N, options?: Parser.Options): Parser.Next; + floatbe(name: N, options?: Parser.Options): Parser.Next; - double(name: string, options?: Parser.Options): Parser; - doublele(name: string, options?: Parser.Options): Parser; - doublebe(name: string, options?: Parser.Options): Parser; + double(name: N, options?: Parser.Options): Parser.Next; + doublele(name: N, options?: Parser.Options): Parser.Next; + doublebe(name: N, options?: Parser.Options): Parser.Next; - string(name: string, options?: Parser.StringOptions): Parser; + string(name: N, options?: Parser.StringOptions): Parser.Next; - buffer(name: string, options: Parser.BufferOptions): Parser; + buffer(name: N, options: Parser.BufferOptions): Parser.Next; - array(name: string, options: Parser.ArrayOptions): Parser; + array(name: N, options: Q): Parser.Next + ? O extends undefined ? Array<{}> : O[] + : T extends string + ? number[] + : never + : never + >; - choice(name: string, options: Parser.ChoiceOptions): Parser; + choice(name: N, options: Q): Parser.Next + ? O extends undefined ? {} : O + : T extends string ? any : never + : never + : never + >; - nest(name: string, options: Parser.NestOptions): Parser; + nest(name: N, options: Q): Parser.Next + ? O extends undefined ? {} : O + : never + : never + >; - skip(length: number): Parser; + skip(length: number): Parser; - endianess(endianess: Parser.Endianness): Parser; /* [sic] */ + endianess(endianess: Parser.Endianness): Parser; /* [sic] */ - namely(alias: string): Parser; + namely(alias: string): Parser; compile(): void; @@ -96,10 +125,8 @@ export interface ParserConstructor { export const Parser: ParserConstructor; export namespace Parser { - type Data = number | string | Array | Parsed | Buffer; - interface Parsed { - [name: string]: Data; - } + type Data = number | string | Array> | Parser | Buffer; + type Parsed = O extends undefined ? {} : O; interface Options { formatter?: ((value: Data) => any); @@ -108,7 +135,7 @@ export namespace Parser { interface StringOptions extends Options { encoding?: string; - length?: number | string | ((this: Parsed) => number); + length?: number | string | ((this: Parser) => number); zeroTerminated?: boolean; greedy?: boolean; stripNull?: boolean; @@ -116,32 +143,34 @@ export namespace Parser { interface BufferOptions extends Options { clone?: boolean; - length?: number | string | ((this: Parsed) => number); + length?: number | string | ((this: Parser) => number); readUntil?: string | ((item: number, buffer: Buffer) => boolean); } interface ArrayOptions extends Options { - type: string | Parser; - length?: number | string | ((this: Parsed) => number); - lengthInBytes?: number | string | ((this: Parsed) => number); + type: string | Parser; + length?: number | string | ((this: Parser) => number); + lengthInBytes?: number | string | ((this: Parser) => number); readUntil?: string | ((item: number, buffer: Buffer) => boolean); } interface ChoiceOptions extends Options { - tag: string | ((this: Parsed) => number); - choices: { [item: number]: Parser | string }; - defaultChoice?: Parser | string; + tag: string | ((this: Parser) => number); + choices: { [item: number]: Parser | string }; + defaultChoice?: Parser | string; } interface NestOptions extends Options { - type: Parser | string; + type: Parser; } type Endianness = 'little' | 'big'; - interface Context { - [name: string]: Parsed; - } + type Valid = + O extends undefined ? P : O & P; + + type Next = + Parser>; }