From 58895031a77c3b7c510534a7d65eb999dc522ca3 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Sat, 11 Oct 2025 12:09:38 +0200 Subject: [PATCH 1/2] add support for generating TypeScript declarations --- README.md | 3 +- bin/pbf | 15 ++- compile.js | 138 +++++++++++++++++++++++++++ package.json | 2 +- test/compile.test.js | 29 +++--- test/fixtures/defaults.d.ts | 16 ++++ test/fixtures/defaults_implicit.d.ts | 27 ++++++ test/fixtures/defaults_proto3.d.ts | 16 ++++ test/fixtures/embedded_type.d.ts | 23 +++++ test/fixtures/map.d.ts | 24 +++++ test/fixtures/oneof.d.ts | 11 +++ test/fixtures/packed.d.ts | 24 +++++ test/fixtures/packed_proto3.d.ts | 28 ++++++ test/fixtures/type_string.d.ts | 22 +++++ test/fixtures/varint.d.ts | 10 ++ test/fixtures/vector_tile.d.ts | 49 ++++++++++ 16 files changed, 419 insertions(+), 18 deletions(-) create mode 100644 test/fixtures/defaults.d.ts create mode 100644 test/fixtures/defaults_implicit.d.ts create mode 100644 test/fixtures/defaults_proto3.d.ts create mode 100644 test/fixtures/embedded_type.d.ts create mode 100644 test/fixtures/map.d.ts create mode 100644 test/fixtures/oneof.d.ts create mode 100644 test/fixtures/packed.d.ts create mode 100644 test/fixtures/packed_proto3.d.ts create mode 100644 test/fixtures/type_string.d.ts create mode 100644 test/fixtures/varint.d.ts create mode 100644 test/fixtures/vector_tile.d.ts diff --git a/README.md b/README.md index c5c2f84..5c17c41 100644 --- a/README.md +++ b/README.md @@ -278,11 +278,12 @@ For an example of a real-world usage of the library, see [vector-tile-js](https: If installed globally, `pbf` provides a binary that compiles `proto` files into JavaScript modules. Usage: ```bash -$ pbf [--no-write] [--no-read] [--legacy] +$ pbf [--no-write] [--no-read] [--legacy] [--ts-declarations] ``` The `--no-write` and `--no-read` switches remove corresponding code in the output. The `--legacy` switch makes it generate a CommonJS module instead of ESM. +The `--ts-declarations` switch makes it generate TypeScript declarations (corresponding to the ESM output). `Pbf` will generate `read` and `write` functions for every message in the schema. For nested messages, their names will be concatenated — e.g. `Message` inside `Test` will produce `readTestMessage` and `writeTestMessage` functions. diff --git a/bin/pbf b/bin/pbf index 7981f06..e79cb1c 100755 --- a/bin/pbf +++ b/bin/pbf @@ -4,14 +4,21 @@ import resolve from 'resolve-protobuf-schema'; import {compileRaw} from '../compile.js'; if (process.argv.length < 3) { - console.error('Usage: pbf [file.proto] [--no-read] [--no-write] [--legacy]'); + console.error('Usage: pbf [file.proto] [--no-read] [--no-write] [--legacy] [--ts-declarations]'); process.exit(0); } -const code = compileRaw(resolve.sync(process.argv[2]), { +const options = { noRead: process.argv.indexOf('--no-read') >= 0, noWrite: process.argv.indexOf('--no-write') >= 0, - legacy: process.argv.indexOf('--legacy') >= 0 -}); + legacy: process.argv.indexOf('--legacy') >= 0, + tsDeclarations: process.argv.indexOf('--ts-declarations') >= 0 +}; +if (options.legacy && options.tsDeclarations) { + console.error('--legacy cannot be used with --ts-declarations'); + process.exit(1); +} + +const code = compileRaw(resolve.sync(process.argv[2]), options); process.stdout.write(code); diff --git a/compile.js b/compile.js index 220de6d..ecb4aab 100644 --- a/compile.js +++ b/compile.js @@ -9,6 +9,9 @@ export function compile(proto) { export function compileRaw(proto, options = {}) { const context = buildDefaults(buildContext(proto, null), proto.syntax); + if (options.tsDeclarations) { + return `${options.dev ? '' : `// TypeScript declarations generated by pbf v${version}\n`}${writeTSContext(context, options)}`; + } return `${options.dev ? '' : `// code generated by pbf v${version}\n`}${writeContext(context, options)}`; } @@ -415,3 +418,138 @@ function getDefaultWriteTest(ctx, field) { function isPacked(field) { return field.options.packed === 'true'; } + +function writeTSContext(ctx, options) { + let code = ''; + if (ctx._proto.fields) code += writeTSMessage(ctx, options); + if (ctx._proto.values) code += writeTSEnum(ctx, options); + + for (let i = 0; i < ctx._children.length; i++) { + code += writeTSContext(ctx._children[i], options); + } + return code; +} + +function writeTSMessage(ctx, options) { + const fields = ctx._proto.fields; + const name = ctx._name; + + let code = '\n'; + + // Generate interface for the message + code += `export interface ${name} {\n`; + + // Track oneof groups to handle them properly + const oneofGroups = new Map(); + for (const field of fields) { + if (field.oneof) { + if (!oneofGroups.has(field.oneof)) { + oneofGroups.set(field.oneof, []); + } + oneofGroups.get(field.oneof).push(field); + } + } + + for (const field of fields) { + const tsType = getTSType(ctx, field); + + if (field.oneof) { + // For oneof fields, make them optional and add the oneof indicator + code += ` ${field.name}?: ${tsType};\n`; + } else { + // Regular fields + const optional = field.repeated ? '' : '?'; + code += ` ${field.name}${optional}: ${tsType};\n`; + } + } + + // Add oneof indicator properties + for (const [oneofName, oneofFields] of oneofGroups) { + const fieldNames = oneofFields.map(f => `"${f.name}"`).join(' | '); + code += ` ${oneofName}?: ${fieldNames};\n`; + } + + code += '}\n\n'; + + // Generate read function declaration + if (!options.noRead) { + const readName = `read${name}`; + code += `export function ${readName}(pbf: any, end?: number): ${name};\n`; + } + + // Generate write function declaration + if (!options.noWrite) { + const writeName = `write${name}`; + code += `export function ${writeName}(obj: ${name}, pbf: any): void;\n`; + } + + return code; +} + +function writeTSEnum(ctx) { + const name = ctx._name; + const values = getEnumValues(ctx); + + let code = `export const ${name}: {\n`; + for (const [key, value] of Object.entries(values)) { + code += ` readonly ${key}: ${value};\n`; + } + code += '};\n\n'; + + return code; +} + +function getTSType(ctx, field) { + if (field.type === 'map') { + const keyType = getTSTypeForFieldType(field.map.from, null, null); + const valueType = getTSTypeForFieldType(field.map.to, null, null); + return `{ [key: ${keyType}]: ${valueType} }`; + } + + if (field.repeated) { + const elementType = getTSTypeForFieldType(field.type, ctx, field); + return `${elementType}[]`; + } + + return getTSTypeForFieldType(field.type, ctx, field); +} + +function getTSTypeForFieldType(type, ctx, field) { + if (ctx) { + const resolvedType = getType(ctx, {type}); + + if (resolvedType) { + if (resolvedType._proto.fields) { + return resolvedType._name; + } + if (resolvedType._proto.values) { + // For enums, return the type of the enum values (number) + return 'number'; + } + } + } + + // Check if field should use string as number (jstype=JS_STRING) + if (field && fieldShouldUseStringAsNumber(field)) { + return 'string'; + } + + switch (type) { + case 'string': return 'string'; + case 'float': + case 'double': return 'number'; + case 'bool': return 'boolean'; + case 'uint32': + case 'uint64': + case 'int32': + case 'int64': + case 'sint32': + case 'sint64': + case 'fixed32': + case 'fixed64': + case 'sfixed32': + case 'sfixed64': return 'number'; + case 'bytes': return 'Uint8Array'; + default: return 'any'; + } +} diff --git a/package.json b/package.json index 499b0f6..e57d69f 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "bench": "node bench/bench.js", "pretest": "eslint *.js compile.js test/*.js test/fixtures/*.js bin/pbf", - "test": "tsc && node --test", + "test": "tsc && node --test test/*.js", "cov": "node --test --experimental-test-covetage", "build": "rollup -c", "prepublishOnly": "npm run test && npm run build" diff --git a/test/compile.test.js b/test/compile.test.js index d2e5157..a39319b 100644 --- a/test/compile.test.js +++ b/test/compile.test.js @@ -6,21 +6,26 @@ import {sync as resolve} from 'resolve-protobuf-schema'; import Pbf from '../index.js'; import {compile, compileRaw} from '../compile.js'; -test('compiles all proto files to proper js', () => { - const files = fs.readdirSync(new URL('fixtures', import.meta.url)); +function testProtoCompilation(options, extension, description) { + test(description, () => { + const files = fs.readdirSync(new URL('fixtures', import.meta.url)); - for (const path of files) { - if (!path.endsWith('.proto')) continue; - const proto = resolve(new URL(`fixtures/${path}`, import.meta.url)); - const js = compileRaw(proto, {dev: true}); + for (const path of files) { + if (!path.endsWith('.proto')) continue; + const proto = resolve(new URL(`fixtures/${path}`, import.meta.url)); + const code = compileRaw(proto, options); - // uncomment to update the fixtures - // fs.writeFileSync(new URL(`fixtures/${path}`.replace('.proto', '.js'), import.meta.url), js); + // uncomment to update the fixtures + // fs.writeFileSync(new URL(`fixtures/${path}`.replace('.proto', extension), import.meta.url), code); - const expectedJS = fs.readFileSync(new URL(`fixtures/${path}`.replace('.proto', '.js'), import.meta.url), 'utf8'); - assert.equal(js, expectedJS); - } -}); + const expectedCode = fs.readFileSync(new URL(`fixtures/${path}`.replace('.proto', extension), import.meta.url), 'utf8'); + assert.equal(code, expectedCode); + } + }); +} + +testProtoCompilation({dev: true}, '.js', 'compiles all proto files to proper js'); +testProtoCompilation({dev: true, tsDeclarations: true}, '.d.ts', 'compiles all proto files to TypeScript declarations'); test('compiles vector tile proto', () => { const proto = resolve(new URL('fixtures/vector_tile.proto', import.meta.url)); diff --git a/test/fixtures/defaults.d.ts b/test/fixtures/defaults.d.ts new file mode 100644 index 0000000..9301ab0 --- /dev/null +++ b/test/fixtures/defaults.d.ts @@ -0,0 +1,16 @@ +export const MessageType: { + readonly UNKNOWN: 0; + readonly GREETING: 1; +}; + + +export interface Envelope { + type?: number; + name?: string; + flag?: boolean; + weight?: number; + id?: number; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; diff --git a/test/fixtures/defaults_implicit.d.ts b/test/fixtures/defaults_implicit.d.ts new file mode 100644 index 0000000..8e60a26 --- /dev/null +++ b/test/fixtures/defaults_implicit.d.ts @@ -0,0 +1,27 @@ +export const MessageType: { + readonly UNKNOWN: 0; + readonly GREETING: 1; +}; + + +export interface CustomType { +} + +export function readCustomType(pbf: any, end?: number): CustomType; +export function writeCustomType(obj: CustomType, pbf: any): void; + +export interface Envelope { + type?: number; + name?: string; + flag?: boolean; + weight?: number; + id?: number; + tags: string[]; + numbers: number[]; + bytes?: Uint8Array; + custom?: CustomType; + types: number[]; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; diff --git a/test/fixtures/defaults_proto3.d.ts b/test/fixtures/defaults_proto3.d.ts new file mode 100644 index 0000000..9301ab0 --- /dev/null +++ b/test/fixtures/defaults_proto3.d.ts @@ -0,0 +1,16 @@ +export const MessageType: { + readonly UNKNOWN: 0; + readonly GREETING: 1; +}; + + +export interface Envelope { + type?: number; + name?: string; + flag?: boolean; + weight?: number; + id?: number; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; diff --git a/test/fixtures/embedded_type.d.ts b/test/fixtures/embedded_type.d.ts new file mode 100644 index 0000000..dbe830b --- /dev/null +++ b/test/fixtures/embedded_type.d.ts @@ -0,0 +1,23 @@ + +export interface EmbeddedType { + value?: string; + sub_field?: EmbeddedTypeContainer; + sub_sub_field?: EmbeddedTypeContainerInner; +} + +export function readEmbeddedType(pbf: any, end?: number): EmbeddedType; +export function writeEmbeddedType(obj: EmbeddedType, pbf: any): void; + +export interface EmbeddedTypeContainer { + values: EmbeddedTypeContainerInner[]; +} + +export function readEmbeddedTypeContainer(pbf: any, end?: number): EmbeddedTypeContainer; +export function writeEmbeddedTypeContainer(obj: EmbeddedTypeContainer, pbf: any): void; + +export interface EmbeddedTypeContainerInner { + value?: string; +} + +export function readEmbeddedTypeContainerInner(pbf: any, end?: number): EmbeddedTypeContainerInner; +export function writeEmbeddedTypeContainerInner(obj: EmbeddedTypeContainerInner, pbf: any): void; diff --git a/test/fixtures/map.d.ts b/test/fixtures/map.d.ts new file mode 100644 index 0000000..0c02fdd --- /dev/null +++ b/test/fixtures/map.d.ts @@ -0,0 +1,24 @@ + +export interface Envelope { + kv?: { [key: string]: string }; + kn?: { [key: string]: number }; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; + +export interface Envelope_FieldEntry1 { + key?: string; + value?: string; +} + +export function readEnvelope_FieldEntry1(pbf: any, end?: number): Envelope_FieldEntry1; +export function writeEnvelope_FieldEntry1(obj: Envelope_FieldEntry1, pbf: any): void; + +export interface Envelope_FieldEntry2 { + key?: string; + value?: number; +} + +export function readEnvelope_FieldEntry2(pbf: any, end?: number): Envelope_FieldEntry2; +export function writeEnvelope_FieldEntry2(obj: Envelope_FieldEntry2, pbf: any): void; diff --git a/test/fixtures/oneof.d.ts b/test/fixtures/oneof.d.ts new file mode 100644 index 0000000..75b6972 --- /dev/null +++ b/test/fixtures/oneof.d.ts @@ -0,0 +1,11 @@ + +export interface Envelope { + id?: number; + int?: number; + float?: number; + string?: string; + value?: "int" | "float" | "string"; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; diff --git a/test/fixtures/packed.d.ts b/test/fixtures/packed.d.ts new file mode 100644 index 0000000..412fcf9 --- /dev/null +++ b/test/fixtures/packed.d.ts @@ -0,0 +1,24 @@ + +export interface NotPacked { + value: number[]; + types: number[]; +} + +export function readNotPacked(pbf: any, end?: number): NotPacked; +export function writeNotPacked(obj: NotPacked, pbf: any): void; + +export interface FalsePacked { + value: number[]; + types: number[]; +} + +export function readFalsePacked(pbf: any, end?: number): FalsePacked; +export function writeFalsePacked(obj: FalsePacked, pbf: any): void; + +export interface Packed { + value: number[]; + types: number[]; +} + +export function readPacked(pbf: any, end?: number): Packed; +export function writePacked(obj: Packed, pbf: any): void; diff --git a/test/fixtures/packed_proto3.d.ts b/test/fixtures/packed_proto3.d.ts new file mode 100644 index 0000000..58c170c --- /dev/null +++ b/test/fixtures/packed_proto3.d.ts @@ -0,0 +1,28 @@ +export const MessageType: { + readonly UNKNOWN: 0; + readonly GREETING: 1; +}; + + +export interface NotPacked { + value: number[]; + types: number[]; +} + +export function readNotPacked(pbf: any, end?: number): NotPacked; +export function writeNotPacked(obj: NotPacked, pbf: any): void; + +export interface FalsePacked { + value: number[]; + types: number[]; +} + +export function readFalsePacked(pbf: any, end?: number): FalsePacked; +export function writeFalsePacked(obj: FalsePacked, pbf: any): void; + +export interface Packed { + value: number[]; +} + +export function readPacked(pbf: any, end?: number): Packed; +export function writePacked(obj: Packed, pbf: any): void; diff --git a/test/fixtures/type_string.d.ts b/test/fixtures/type_string.d.ts new file mode 100644 index 0000000..404dd03 --- /dev/null +++ b/test/fixtures/type_string.d.ts @@ -0,0 +1,22 @@ + +export interface TypeString { + int?: string; + long?: string; + boolVal?: boolean; + float?: string; + default_implicit?: string; + default_explicit?: string; +} + +export function readTypeString(pbf: any, end?: number): TypeString; +export function writeTypeString(obj: TypeString, pbf: any): void; + +export interface TypeNotString { + int?: number; + long?: number; + boolVal?: boolean; + float?: number; +} + +export function readTypeNotString(pbf: any, end?: number): TypeNotString; +export function writeTypeNotString(obj: TypeNotString, pbf: any): void; diff --git a/test/fixtures/varint.d.ts b/test/fixtures/varint.d.ts new file mode 100644 index 0000000..9713106 --- /dev/null +++ b/test/fixtures/varint.d.ts @@ -0,0 +1,10 @@ + +export interface Envelope { + int?: number; + uint?: number; + long?: number; + ulong?: number; +} + +export function readEnvelope(pbf: any, end?: number): Envelope; +export function writeEnvelope(obj: Envelope, pbf: any): void; diff --git a/test/fixtures/vector_tile.d.ts b/test/fixtures/vector_tile.d.ts new file mode 100644 index 0000000..a466e49 --- /dev/null +++ b/test/fixtures/vector_tile.d.ts @@ -0,0 +1,49 @@ + +export interface Tile { + layers: TileLayer[]; +} + +export function readTile(pbf: any, end?: number): Tile; +export function writeTile(obj: Tile, pbf: any): void; +export const TileGeomType: { + readonly UNKNOWN: 0; + readonly POINT: 1; + readonly LINESTRING: 2; + readonly POLYGON: 3; +}; + + +export interface TileValue { + string_value?: string; + float_value?: number; + double_value?: number; + int_value?: number; + uint_value?: number; + sint_value?: number; + bool_value?: boolean; +} + +export function readTileValue(pbf: any, end?: number): TileValue; +export function writeTileValue(obj: TileValue, pbf: any): void; + +export interface TileFeature { + id?: number; + tags: number[]; + type?: number; + geometry: number[]; +} + +export function readTileFeature(pbf: any, end?: number): TileFeature; +export function writeTileFeature(obj: TileFeature, pbf: any): void; + +export interface TileLayer { + version?: number; + name?: string; + features: TileFeature[]; + keys: string[]; + values: TileValue[]; + extent?: number; +} + +export function readTileLayer(pbf: any, end?: number): TileLayer; +export function writeTileLayer(obj: TileLayer, pbf: any): void; From a7530a740da8373526aba3a307be54937abf0a43 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Sat, 11 Oct 2025 14:08:44 +0200 Subject: [PATCH 2/2] Allow null as well as undefined --- compile.js | 10 ++++++---- test/fixtures/defaults.d.ts | 10 +++++----- test/fixtures/defaults_implicit.d.ts | 14 +++++++------- test/fixtures/defaults_proto3.d.ts | 10 +++++----- test/fixtures/embedded_type.d.ts | 8 ++++---- test/fixtures/map.d.ts | 12 ++++++------ test/fixtures/oneof.d.ts | 8 ++++---- test/fixtures/type_string.d.ts | 20 ++++++++++---------- test/fixtures/varint.d.ts | 8 ++++---- test/fixtures/vector_tile.d.ts | 24 ++++++++++++------------ 10 files changed, 63 insertions(+), 61 deletions(-) diff --git a/compile.js b/compile.js index ecb4aab..2422923 100644 --- a/compile.js +++ b/compile.js @@ -455,11 +455,13 @@ function writeTSMessage(ctx, options) { if (field.oneof) { // For oneof fields, make them optional and add the oneof indicator - code += ` ${field.name}?: ${tsType};\n`; + code += ` ${field.name}?: ${tsType} | null;\n`; + } else if (field.repeated) { + // Repeated fields are required arrays + code += ` ${field.name}: ${tsType};\n`; } else { - // Regular fields - const optional = field.repeated ? '' : '?'; - code += ` ${field.name}${optional}: ${tsType};\n`; + // Regular optional fields + code += ` ${field.name}?: ${tsType} | null;\n`; } } diff --git a/test/fixtures/defaults.d.ts b/test/fixtures/defaults.d.ts index 9301ab0..9707b78 100644 --- a/test/fixtures/defaults.d.ts +++ b/test/fixtures/defaults.d.ts @@ -5,11 +5,11 @@ export const MessageType: { export interface Envelope { - type?: number; - name?: string; - flag?: boolean; - weight?: number; - id?: number; + type?: number | null; + name?: string | null; + flag?: boolean | null; + weight?: number | null; + id?: number | null; } export function readEnvelope(pbf: any, end?: number): Envelope; diff --git a/test/fixtures/defaults_implicit.d.ts b/test/fixtures/defaults_implicit.d.ts index 8e60a26..1c03472 100644 --- a/test/fixtures/defaults_implicit.d.ts +++ b/test/fixtures/defaults_implicit.d.ts @@ -11,15 +11,15 @@ export function readCustomType(pbf: any, end?: number): CustomType; export function writeCustomType(obj: CustomType, pbf: any): void; export interface Envelope { - type?: number; - name?: string; - flag?: boolean; - weight?: number; - id?: number; + type?: number | null; + name?: string | null; + flag?: boolean | null; + weight?: number | null; + id?: number | null; tags: string[]; numbers: number[]; - bytes?: Uint8Array; - custom?: CustomType; + bytes?: Uint8Array | null; + custom?: CustomType | null; types: number[]; } diff --git a/test/fixtures/defaults_proto3.d.ts b/test/fixtures/defaults_proto3.d.ts index 9301ab0..9707b78 100644 --- a/test/fixtures/defaults_proto3.d.ts +++ b/test/fixtures/defaults_proto3.d.ts @@ -5,11 +5,11 @@ export const MessageType: { export interface Envelope { - type?: number; - name?: string; - flag?: boolean; - weight?: number; - id?: number; + type?: number | null; + name?: string | null; + flag?: boolean | null; + weight?: number | null; + id?: number | null; } export function readEnvelope(pbf: any, end?: number): Envelope; diff --git a/test/fixtures/embedded_type.d.ts b/test/fixtures/embedded_type.d.ts index dbe830b..1d64244 100644 --- a/test/fixtures/embedded_type.d.ts +++ b/test/fixtures/embedded_type.d.ts @@ -1,8 +1,8 @@ export interface EmbeddedType { - value?: string; - sub_field?: EmbeddedTypeContainer; - sub_sub_field?: EmbeddedTypeContainerInner; + value?: string | null; + sub_field?: EmbeddedTypeContainer | null; + sub_sub_field?: EmbeddedTypeContainerInner | null; } export function readEmbeddedType(pbf: any, end?: number): EmbeddedType; @@ -16,7 +16,7 @@ export function readEmbeddedTypeContainer(pbf: any, end?: number): EmbeddedTypeC export function writeEmbeddedTypeContainer(obj: EmbeddedTypeContainer, pbf: any): void; export interface EmbeddedTypeContainerInner { - value?: string; + value?: string | null; } export function readEmbeddedTypeContainerInner(pbf: any, end?: number): EmbeddedTypeContainerInner; diff --git a/test/fixtures/map.d.ts b/test/fixtures/map.d.ts index 0c02fdd..9642df1 100644 --- a/test/fixtures/map.d.ts +++ b/test/fixtures/map.d.ts @@ -1,23 +1,23 @@ export interface Envelope { - kv?: { [key: string]: string }; - kn?: { [key: string]: number }; + kv?: { [key: string]: string } | null; + kn?: { [key: string]: number } | null; } export function readEnvelope(pbf: any, end?: number): Envelope; export function writeEnvelope(obj: Envelope, pbf: any): void; export interface Envelope_FieldEntry1 { - key?: string; - value?: string; + key?: string | null; + value?: string | null; } export function readEnvelope_FieldEntry1(pbf: any, end?: number): Envelope_FieldEntry1; export function writeEnvelope_FieldEntry1(obj: Envelope_FieldEntry1, pbf: any): void; export interface Envelope_FieldEntry2 { - key?: string; - value?: number; + key?: string | null; + value?: number | null; } export function readEnvelope_FieldEntry2(pbf: any, end?: number): Envelope_FieldEntry2; diff --git a/test/fixtures/oneof.d.ts b/test/fixtures/oneof.d.ts index 75b6972..9b4a155 100644 --- a/test/fixtures/oneof.d.ts +++ b/test/fixtures/oneof.d.ts @@ -1,9 +1,9 @@ export interface Envelope { - id?: number; - int?: number; - float?: number; - string?: string; + id?: number | null; + int?: number | null; + float?: number | null; + string?: string | null; value?: "int" | "float" | "string"; } diff --git a/test/fixtures/type_string.d.ts b/test/fixtures/type_string.d.ts index 404dd03..8db5c07 100644 --- a/test/fixtures/type_string.d.ts +++ b/test/fixtures/type_string.d.ts @@ -1,21 +1,21 @@ export interface TypeString { - int?: string; - long?: string; - boolVal?: boolean; - float?: string; - default_implicit?: string; - default_explicit?: string; + int?: string | null; + long?: string | null; + boolVal?: boolean | null; + float?: string | null; + default_implicit?: string | null; + default_explicit?: string | null; } export function readTypeString(pbf: any, end?: number): TypeString; export function writeTypeString(obj: TypeString, pbf: any): void; export interface TypeNotString { - int?: number; - long?: number; - boolVal?: boolean; - float?: number; + int?: number | null; + long?: number | null; + boolVal?: boolean | null; + float?: number | null; } export function readTypeNotString(pbf: any, end?: number): TypeNotString; diff --git a/test/fixtures/varint.d.ts b/test/fixtures/varint.d.ts index 9713106..a622faa 100644 --- a/test/fixtures/varint.d.ts +++ b/test/fixtures/varint.d.ts @@ -1,9 +1,9 @@ export interface Envelope { - int?: number; - uint?: number; - long?: number; - ulong?: number; + int?: number | null; + uint?: number | null; + long?: number | null; + ulong?: number | null; } export function readEnvelope(pbf: any, end?: number): Envelope; diff --git a/test/fixtures/vector_tile.d.ts b/test/fixtures/vector_tile.d.ts index a466e49..27356ae 100644 --- a/test/fixtures/vector_tile.d.ts +++ b/test/fixtures/vector_tile.d.ts @@ -14,22 +14,22 @@ export const TileGeomType: { export interface TileValue { - string_value?: string; - float_value?: number; - double_value?: number; - int_value?: number; - uint_value?: number; - sint_value?: number; - bool_value?: boolean; + string_value?: string | null; + float_value?: number | null; + double_value?: number | null; + int_value?: number | null; + uint_value?: number | null; + sint_value?: number | null; + bool_value?: boolean | null; } export function readTileValue(pbf: any, end?: number): TileValue; export function writeTileValue(obj: TileValue, pbf: any): void; export interface TileFeature { - id?: number; + id?: number | null; tags: number[]; - type?: number; + type?: number | null; geometry: number[]; } @@ -37,12 +37,12 @@ export function readTileFeature(pbf: any, end?: number): TileFeature; export function writeTileFeature(obj: TileFeature, pbf: any): void; export interface TileLayer { - version?: number; - name?: string; + version?: number | null; + name?: string | null; features: TileFeature[]; keys: string[]; values: TileValue[]; - extent?: number; + extent?: number | null; } export function readTileLayer(pbf: any, end?: number): TileLayer;