ts-json-schema-generator icon indicating copy to clipboard operation
ts-json-schema-generator copied to clipboard

Error: Reference type not set yet

Open domoritz opened this issue 5 years ago • 14 comments

In https://github.com/vega/vega-lite/pull/5290 and https://travis-ci.org/vega/vega-lite/jobs/571493756.

domoritz avatar Aug 13 '19 19:08 domoritz

We can reproduce this with keyof HTMLBodyElementEventMap and also Window. It looks like the Window type has some complications we don't deal with well.

Two solutions are: 1) support Window 2) ignore the values if we do keyof.

domoritz avatar Aug 18 '19 10:08 domoritz

Omit + recursion give the same error:

export interface Comment {
    text: string;
    reply: Omit<Comment, 'reply'>;
}

dartess avatar Feb 15 '20 11:02 dartess

I'm getting something similar with this example:

export interface X {
  x: string;
}

export interface Y {
  y: string;
}

export type Inner<T> = {
  inner: Wrapper<T>[];
};

export type Wrapper<T> = T & Inner<Y>;

export type Output = Wrapper<X>;

zsalzbank avatar Feb 19 '20 01:02 zsalzbank

I'd love to fix this if somebody could point me in the right direction.

zsalzbank avatar Feb 20 '20 14:02 zsalzbank

The issue is somewhere in the cycle tracking, I think. The best way to debug this is to setup the repo, create a small example, and then step through the code with a debugger (follow package.json debug).

domoritz avatar Feb 20 '20 16:02 domoritz

From @Cyrus-d

in my repository, I have implemented the FunctionTypeFormatter to fulfil my needs. so to reproduce the problem In your repository I have changed the test as follow:

export type MyType = MyElement;

type MyFunction = MyElement | null;

interface MyElement<T extends string | MyFunction = string | MyFunction> {
    type: T;
}

this will throw Reference type ID not set yet error.

I think the problem is related to UnionType that trying to access ReferenceType to early for this line:

type MyFunction = MyElement | null;

For now, to solve it I have added the following line of the code to the CircularReferenceNodeParser file.

it will work however it will use ids for the interface names:

interface-572149719-68-159-572149719-0-160

I can overcome this by setting expose: "all", not sure if its normal behaviour?

here is the repository:

https://github.com/Cyrus-d/ts-to-json/tree/original

Test result with expose: "all":

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#/definitions/MyType",
    "definitions": {
        "MyType": {
            "$ref": "#/definitions/MyElement"
        },
        "MyElement": {
            "type": "object",
            "properties": {
                "type": {
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "$ref": "#/definitions/MyFunction"
                        }
                    ]
                }
            },
            "required": [
                "type"
            ],
            "additionalProperties": false
        },
        "MyFunction": {
            "anyOf": [
                {
                    "$ref": "#/definitions/MyElement"
                },
                {
                    "type": "null"
                }
            ]
        }
    }
}

Test result with expose: "export":

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#/definitions/MyType",
    "definitions": {
        "MyType": {
            "type": "object",
            "properties": {
                "type": {
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "anyOf": [
                                {
                                    "$ref": "#/definitions/interface-572149719-68-159-572149719-0-160"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    ]
                }
            },
            "required": [
                "type"
            ],
            "additionalProperties": false
        },
        "interface-572149719-68-159-572149719-0-160": {
            "type": "object",
            "properties": {
                "type": {
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "anyOf": [
                                {
                                    "$ref": "#/definitions/interface-572149719-68-159-572149719-0-160"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    ]
                }
            },
            "required": [
                "type"
            ],
            "additionalProperties": false
        }
    }
}

domoritz avatar Mar 11 '20 18:03 domoritz

Hi,

Here's an example that reproduces the issue for me: test.ts

import { Test2 } from './test2';

export interface Test {
  test2: Test2;
}

test2.ts

import { Test } from './test';

export interface Test2 {
  test?: Partial<Test>;
}

Run:

ts-json-schema-generator --path test.ts --tsconfig tsconfig.json --type Test --out test.json

orgads avatar Apr 06 '20 15:04 orgads

Has anyone discovered a work around for this?

randygylling avatar Aug 12 '20 18:08 randygylling

I have created a repository with different schema generators to compare its capability: https://github.com/Guidewire/ts-to-json-schema-tests. By introducing the custom formatters feature here (it's exactly what we need!), I was able to parse simple type with a callback. This problem still occurs for more advanced types. I've fixed recursive problems in typescript-json-schema in this PR so, it may be useful to fix this.

I didn't have time to dive into this codebase and actually this one is a bit harder to understand (much more abstraction), but the custom formatters functionality is something we need so maybe we will do something with this soon :P

darkowic avatar Nov 21 '20 19:11 darkowic

[Edited to provide better test case examples]

Is there a status update on this?

I'm currently running into this issue (circular type references) in the following cases (in case more test cases are needed):

(Note: I'm using custom generator to handle unknown function types.)

broofa avatar Jun 08 '22 19:06 broofa

Breadcrumb for others: I ended up switching to typescript-json-schema. It handles this issue, as well as a number of other issues I was running into (such as module resolution in the context of yarn workspaces.)

broofa avatar Jun 10 '22 02:06 broofa

This is still reproducing in "ts-json-schema-generator": "1.1.2"

andreicioromila avatar Nov 19 '22 12:11 andreicioromila

The schema generator landscape is in a bit of a weird spot ATM.

I tried to switch to this project, as the other is in maintenance mode and recommends this, but schema conversion fails with this error, which is still open after almost four years.

❯ ts-json-schema-generator --no-type-check --path ./npm/src/style.ts --type Style --tsconfig ./tsconfig.json
/usr/local/lib/node_modules/ts-json-schema-generator/dist/ts-json-schema-generator.js:95
        throw error;
        ^

Error: Reference type not set yet
    at ReferenceType.getType (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/Type/ReferenceType.js:32:19)
    at derefType (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/Utils/derefType.js:13:31)
    at derefAndFlattenUnions (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/NodeParser/IntersectionNodeParser.js:33:47)
    at /usr/local/lib/node_modules/ts-json-schema-generator/dist/src/NodeParser/IntersectionNodeParser.js:36:28
    at Array.reduce (<anonymous>)
    at derefAndFlattenUnions (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/NodeParser/IntersectionNodeParser.js:35:30)
    at Array.map (<anonymous>)
    at translate (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/NodeParser/IntersectionNodeParser.js:46:26)
    at IntersectionNodeParser.createType (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/NodeParser/IntersectionNodeParser.js:28:16)
    at ChainNodeParser.createType (/usr/local/lib/node_modules/ts-json-schema-generator/dist/src/ChainNodeParser.js:28:54)

Node.js v20.2.0

bdarcus avatar May 25 '23 14:05 bdarcus

I was getting this error due to the following:

type A = {
  x: number;
  o: {
    type: 'foo' | 'bar';
    otherType?: A['o']['type'] | null;
  }
}

The issue was with the self-reference, so I had to do the following workaround:

type FooBar = 'foo' | 'bar';

type A = {
  x: number;
  o: {
    type: FooBar;
    otherType?: FooBar | null;
  }
}

themetalfleece avatar Mar 07 '24 07:03 themetalfleece