Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for conditional type nodes #100

Closed
kayahr opened this issue May 31, 2019 · 4 comments
Closed

Add support for conditional type nodes #100

kayahr opened this issue May 31, 2019 · 4 comments

Comments

@kayahr
Copy link
Contributor

kayahr commented May 31, 2019

Because of YousefED/typescript-json-schema#173 I'm currently trying to migrate to ts-json-schema-generator. The first problem I have with the new tool is missing support for conditional type nodes which worked fine with the typescript-json-schema tool. Here is a minimal example:

export type TypeName<T> =
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    "object";

export type TestJSON = TypeName<string>;

When I try to generate the schema for TestJSON with this tool then I get this error message:

UnknownNodeError: Unknown node "TypeName<string>" (ts.SyntaxKind = 176)

I really like the clean structure of the new tool and it looks pretty straight forward how to implement this feature by adding a ConditionalTypeNodeParser class like this:

export class ConditionalTypeNodeParser implements SubNodeParser {
    public constructor(
        private typeChecker: ts.TypeChecker,
        private childNodeParser: NodeParser,
    ) {
    }

    public supportsNode(node: ts. ConditionalTypeNode): boolean {
        return node.kind === ts.SyntaxKind.ConditionalType;
    }

    public createType(node: ts.ConditionalTypeNode, context: Context): BaseType {
        ... magic here ...
    }
}

But unfortunately I lack the skills to implement the createType method. In theory the method has to check if node.checkType is assignable to node.extendsType and then returns node.trueType or node.falseType. But I don't know if this assignability check must be written from scratch here or if TypeScript already exposes some functionality to do this. And it gets more complicated if the check type is a union type so TypeName<string | Date> is resolved to "string" | "object" in this example.

@domoritz
Copy link
Member

This is closely related to #71

@kayahr
Copy link
Contributor Author

kayahr commented Jun 1, 2019

I gave it a try and implemented somewhat working conditional type support. It works for the simple stuff I need and a few more complex use cases and also for basic exclude types but there are also type combinations which don't work at all... I'm not really happy with this implementation so I'm not sure if a pull request makes sense. It feels to complicated and I'm still not sure if it isn't possible to use some TypeScript internals to do all this... But maybe it is an acceptable "good enough for now" solution?

https://github.com/vega/ts-json-schema-generator/compare/master...iplabs:feature/conditional-type?expand=1

I also added some tests which shows what is already working.

@domoritz
Copy link
Member

domoritz commented Jun 1, 2019

Thank you! I made a PR in #105 so we can look at it easily. It does look a bit complicated but the overall structure (having a parser, tests, ...) is a useful start.

@kayahr
Copy link
Contributor Author

kayahr commented Jun 26, 2019

PR is merged and for my project conditional types are now working very well. Closing the issue.

@kayahr kayahr closed this as completed Jun 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants