Skip to content

[BUG] Typescript error when using property literal type with optional fields #266

@lukaskurz

Description

@lukaskurz

Expected Behaviour

Generate typescript definitions from json schema.
Generate interface that defines some fields, that are optional and also defines a type for all other properties of that object.

interface Foo {
    bar?: string;
    baz?: string;
    [k: string]: string;
}

However this throws an Type Error, due to prop?:string translating to prop: string | undefined.
To fix this, undefined has to be added to the key-value definition.

interface Foo {
    bar?: string;
    baz?: string;
    [k: string]: string | undefined;
}

json2ts should do this automatically

Actual Behaviour

json2ts does not add that | undefined and generates an invalid typescript definition.

Reproduce this behaviour

json2ts: 7.1.0
node: 10.16.1
typescript: 3.6.4
os: ubuntu 18.04

json schema

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "Benchmark result report format",
    "type": "array",
    "additionalItems": false,
    "items": {
        "description": "executions of benchmark tests.",
        "type": "object",
        "properties": {
            "test": {
                "type": "string",
                "description": "name of the benchmark session."
            },
            "tags": {
                "description": "set of tags associated with this benchmark session. tags can be used to filter benchmark execution runs and for execution results comparison criteria (for generic, supplemental information, use annotations)",
                "type": "object",
                "properties": {
                    "jvm": {
                        "type": "string",
                        "description": "predefined tag to identify jvm flavors"
                    },
                    "clr": {
                        "type": "string",
                        "description": "predefined tag to identify clr versions"
                    },
                    "runtime": {
                        "type": "string",
                        "description": "predefined tag to identify runtime used to execute tests (eg. Node.js 8.10, go1.12.1)"
                    },
                    "agentOperationMode": {
                        "type": "string",
                        "enum": [
                            "disabled",
                            "CIM"
                        ],
                        "description": "defines specific agent operational modes"
                    }
                },
                "additionalProperties": {
                    "type": "string"
                }
            },
            "annotations": {
                "description": "Annotations contain benchmark execution specific information. This information is purely informational and cannot be used to in test result filtering or comparison.",
                "type": "object",
                "additionalProperties": {
                    "type": "string"
                }
            },
            "iterations": {
                "description": "results of each iteration executed in the benchmark session",
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "numOperations": {
                            "type": "number",
                            "description": "number of operations executed in this iteration"
                        },
                        "measurements": {
                            "$ref": "#/definitions/MeasurementValueContainer"
                        }
                    },
                    "required": [ "numOperations", "measurements"],
                    "additionalItems": false
                }
            },
            "measurements": {
                "description": "discrete measurements done outside of iterations scope. e.g. measure memory before and after benchmark session",
                "$ref": "#/definitions/MeasurementValueContainer"
            },
            "profilingResults": {
                "description": "result string of optional profiling session. to be elaborated in more detail.",
                "type": "string"
            },
            "units": {
                "description": "optional unit definitions for measurements",
                "type": "object",
                "properties": {},
                "additionalProperties": {
                    "type": "string",
                    "default": "ns/op",
                    "examples": [
                        "ns",
                        "μs",
                        "ms",
                        "ns/op",
                        "μs/op",
                        "ms/op",
                        "bytes/sec",
                        "kb/sec",
                        "mb/sec",
                        "req/sec",
                        "bytes",
                        "kB",
                        "MB",
                        "GB",
                        "KiB",
                        "MiB",
                        "GiB"
                    ]
                }
            }
        },
        "additionalProperties": false,
        "required": [
            "test",
            "iterations"
        ]
    },
    "definitions": {
        "MeasurementValueContainer": {
            "type": "object",
            "description": "container for measurement values.",
            "properties": {
                "duration": {
                    "type": "number",
                    "description": "wall clock duration"
                }
            },
            "additionalProperties": {
                "type": "number"
            }
        }
    }
}

ts definitions

/* 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 type BenchmarkResultReportFormat = {
    /**
     * name of the benchmark session.
     */
    test: string;
    /**
     * set of tags associated with this benchmark session. tags can be used to filter benchmark execution runs and for execution results comparison criteria (for generic, supplemental information, use annotations)
     */
    tags?: {
        /**
         * predefined tag to identify jvm flavors
         */
        jvm?: string;
        /**
         * predefined tag to identify clr versions
         */
        clr?: string;
        /**
         * predefined tag to identify runtime used to execute tests (eg. Node.js 8.10, go1.12.1)
         */
        runtime?: string;
        /**
         * defines specific agent operational modes
         */
        agentOperationMode?: "disabled" | "CIM";
        [k: string]: string;
    };
    /**
     * Annotations contain benchmark execution specific information. This information is purely informational and cannot be used to in test result filtering or comparison.
     */
    annotations?: {
        [k: string]: string;
    };
    /**
     * results of each iteration executed in the benchmark session
     */
    iterations: {
        /**
         * number of operations executed in this iteration
         */
        numOperations: number;
        measurements: MeasurementValueContainer;
        [k: string]: any;
    }[];
    /**
     * discrete measurements done outside of iterations scope. e.g. measure memory before and after benchmark session
     */
    measurements?: {
        /**
         * wall clock duration
         */
        duration?: number;
        [k: string]: number;
    };
    /**
     * result string of optional profiling session. to be elaborated in more detail.
     */
    profilingResults?: string;
    /**
     * optional unit definitions for measurements
     */
    units?: {
        [k: string]: string;
    };
}[];

/**
 * container for measurement values.
 */
export interface MeasurementValueContainer {
    /**
     * wall clock duration
     */
    duration?: number;
    [k: string]: number;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions