Skip to content

Commit 2602888

Browse files
committed
Add exactOptionalPropertyTypes option
1 parent 7c6bad4 commit 2602888

8 files changed

+73
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ See [server demo](example) and [browser demo](https://github.com/bcherny/json-sc
139139
| declareExternallyReferenced | boolean | `true` | Declare external schemas referenced via `$ref`? |
140140
| enableConstEnums | boolean | `true` | Prepend enums with [`const`](https://www.typescriptlang.org/docs/handbook/enums.html#computed-and-constant-members)? |
141141
| inferStringEnumKeysFromValues | boolean | `false` | Create enums from JSON enums with eponymous keys |
142+
| exactOptionalPropertyTypes | boolean | `false` | Append all optional property signatures with `\| undefined` so that they are strictly typed in accordance with TypeScript's [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes) option. |
142143
| format | boolean | `true` | Format code? Set this to `false` to improve performance. |
143144
| ignoreMinAndMaxItems | boolean | `false` | Ignore maxItems and minItems for `array` types, preventing tuples being generated. |
144145
| maxItems | number | `20` | Maximum number of unioned tuples to emit when representing bounded-size array types, before falling back to emitting unbounded arrays. Increase this to improve precision of emitted types, decrease it to improve performance, or set it to `-1` to ignore `maxItems`.

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.ts

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ main(
2020
'additionalProperties',
2121
'declareExternallyReferenced',
2222
'enableConstEnums',
23+
'exactOptionalPropertyTypes',
2324
'format',
2425
'ignoreMinAndMaxItems',
2526
'strictIndexSignatures',

src/generator.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ function generateInterface(ast: TInterface, options: Options): string {
308308
escapeKeyName(keyName) +
309309
(isRequired ? '' : '?') +
310310
': ' +
311-
type,
311+
type +
312+
(!isRequired && options.exactOptionalPropertyTypes ? ' | undefined' : ''),
312313
)
313314
.join('\n') +
314315
'\n' +

src/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ export interface Options {
5252
* Create enums from JSON enums with eponymous keys
5353
*/
5454
inferStringEnumKeysFromValues: boolean
55+
/**
56+
* Append all optional property signatures with `| undefined` so that they are strictly typed in accordance with
57+
* TypeScript's [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes)
58+
* option.
59+
*/
60+
exactOptionalPropertyTypes: boolean
5561
/**
5662
* Format code? Set this to `false` to improve performance.
5763
*/
@@ -100,6 +106,7 @@ export const DEFAULT_OPTIONS: Options = {
100106
declareExternallyReferenced: true,
101107
enableConstEnums: true,
102108
inferStringEnumKeysFromValues: false,
109+
exactOptionalPropertyTypes: false,
103110
format: true,
104111
ignoreMinAndMaxItems: false,
105112
maxItems: 20,

test/__snapshots__/test/test.ts.md

+27
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,33 @@ Generated by [AVA](https://avajs.dev).
23262326
}␊
23272327
`
23282328

2329+
## options.exactOptionalPropertyTypes.js
2330+
2331+
> Expected output to match snapshot for e2e test: options.exactOptionalPropertyTypes.js
2332+
2333+
`/* eslint-disable */␊
2334+
/**␊
2335+
* This file was automatically generated by json-schema-to-typescript.␊
2336+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
2337+
* and run json-schema-to-typescript to regenerate this file.␊
2338+
*/␊
2339+
2340+
export interface ExactOptionalPropertyTypes {␊
2341+
maybe?: string | undefined;␊
2342+
complex?:␊
2343+
| {␊
2344+
maybe?: string | undefined;␊
2345+
[k: string]: Leaf;␊
2346+
}␊
2347+
| undefined;␊
2348+
[k: string]: string;␊
2349+
}␊
2350+
export interface Leaf {␊
2351+
maybe?: string | undefined;␊
2352+
[k: string]: unknown;␊
2353+
}␊
2354+
`
2355+
23292356
## options.format.js
23302357

23312358
> Expected output to match snapshot for e2e test: options.format.js

test/__snapshots__/test/test.ts.snap

75 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export const input = {
2+
title: 'ExactOptionalPropertyTypes',
3+
type: 'object',
4+
properties: {
5+
maybe: {
6+
type: 'string',
7+
},
8+
complex: {
9+
type: 'object',
10+
properties: {
11+
maybe: {
12+
type: 'string',
13+
},
14+
},
15+
additionalProperties: {
16+
title: 'Leaf',
17+
type: 'object',
18+
properties: {
19+
maybe: {
20+
type: 'string',
21+
},
22+
},
23+
},
24+
},
25+
},
26+
additionalProperties: {
27+
type: 'string',
28+
}
29+
}
30+
31+
export const options = {
32+
exactOptionalPropertyTypes: true,
33+
}

0 commit comments

Comments
 (0)