diff --git a/.gitignore b/.gitignore index bdd8e215..bb96b4ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ .DS_Store +.idea/ npm-debug.log node_modules *.js *.map dist/ -dist_tests/ \ No newline at end of file +dist_tests/ diff --git a/.npmignore b/.npmignore index 1f03aff1..5fdd0760 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,5 @@ .DS_Store +.idea .vscode npm-debug.log node_modules diff --git a/README.md b/README.md index e4ab0b2b..bcecfc08 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ See [server demo](example) and [browser demo](https://github.com/bcherny/json-sc | enableConstEnums | boolean | `true` | Prepend enums with [`const`](https://www.typescriptlang.org/docs/handbook/enums.html#computed-and-constant-members)? | | style | object | `{ bracketSpacing: false, printWidth: 120, semi: true, singleQuote: false, tabWidth: 2, trailingComma: 'none', useTabs: false }` | A [Prettier](https://prettier.io/docs/en/options.html) configuration | | unreachableDefinitions | boolean | `false` | Generates code for `definitions` that aren't referenced by the schema. | +| strictIndexSignatures | boolean | `false` | Append all index signatures with `| undefined` so that they are strictly typed. | | $refOptions | object | `{}` | [$RefParser](https://github.com/BigstickCarpet/json-schema-ref-parser) Options, used when resolving `$ref`s | ## CLI diff --git a/src/generator.ts b/src/generator.ts index 9217871b..9b9d3f1e 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -145,6 +145,16 @@ function declareNamedTypes( } function generateType(ast: AST, options: Options): string { + const type = generateRawType(ast, options) + + if (options.strictIndexSignatures && ast.keyName === '[k: string]') { + return `${type} | undefined` + } + + return type +} + +function generateRawType(ast: AST, options: Options): string { log(whiteBright.bgMagenta('generator'), ast) if (hasStandaloneName(ast)) { diff --git a/src/index.ts b/src/index.ts index 0f55176f..aefa0dbb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,12 @@ export interface Options { * Prepend enums with [`const`](https://www.typescriptlang.org/docs/handbook/enums.html#computed-and-constant-members)? */ enableConstEnums: boolean + /** + * Append all index signatures with `| undefined` so that they are strictly typed. + * + * This is required to be compatible with `strictNullChecks`. + */ + strictIndexSignatures: boolean /** * A [Prettier](https://prettier.io/docs/en/options.html) configuration. */ @@ -57,6 +63,7 @@ export const DEFAULT_OPTIONS: Options = { cwd: process.cwd(), declareExternallyReferenced: true, enableConstEnums: true, // by default, avoid generating code + strictIndexSignatures: false, style: { bracketSpacing: false, printWidth: 120, diff --git a/test/__snapshots__/test/test.ts.md b/test/__snapshots__/test/test.ts.md index 407ecf16..129ea76a 100644 --- a/test/__snapshots__/test/test.ts.md +++ b/test/__snapshots__/test/test.ts.md @@ -9425,3 +9425,20 @@ Generated by [AVA](https://ava.li). [k: string]: any;␊ }␊ ` + +## strictIndexSignatures.js + +> Snapshot 1 + + `/* tslint:disable */␊ + /**␊ + * This file was automatically generated by json-schema-to-typescript.␊ + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊ + * and run json-schema-to-typescript to regenerate this file.␊ + */␊ + ␊ + export interface StrictIndexSignatures {␊ + maybe?: string;␊ + [k: string]: string | undefined;␊ + }␊ + ` diff --git a/test/__snapshots__/test/test.ts.snap b/test/__snapshots__/test/test.ts.snap index e2744647..ab1bf00c 100644 Binary files a/test/__snapshots__/test/test.ts.snap and b/test/__snapshots__/test/test.ts.snap differ diff --git a/test/e2e/strictIndexSignatures.ts b/test/e2e/strictIndexSignatures.ts new file mode 100644 index 00000000..0b7f0e16 --- /dev/null +++ b/test/e2e/strictIndexSignatures.ts @@ -0,0 +1,16 @@ +export const input = { + title: 'StrictIndexSignatures', + type: 'object', + properties: { + maybe: { + type: 'string' + } + }, + additionalProperties: { + type: 'string' + } +} + +export const options = { + strictIndexSignatures: true +}