1

I am creating a typescript interface corresponding to a json schema. I have the following field in my json schema:

         "styles": {
            "title": "Style Definitions",
            "description": "Style definition",
            "type": "object",
            "patternProperties": {
                "^.*$": {
                    "oneOf": [
                        { "$ref": "#/definitions/definition1" },
                        { "$ref": "#/definitions/definition2" }
                    ]
                }
            }
         }

I want to create my interface something like this:

interface Styles {
    [key: string]: Definition1 | Definition2;
} 

But this isn't right and doesn't capture the correct meaning of the json schema. Can someone tell me how to do this?

How can I write this thing in my typescript interface?

RichaS
  • 219
  • 3
  • 14

1 Answers1

0

I ran into this same question. In my situation, I had been hoping that the openapi-typescript library would support converting schemas which use patternProperties into typescript interfaces but it does not appear to support this presently. (See the issue I opened).

The situation with patternProperties really boils down to whether we can restrict a string in Typescript only to values that match a given regex. This is answered here. The bottomline is that regex restrictions are not directly supported (though there is an open proposal for that functionality to be included), so being able to generically convert schemas which utilize patternProperties to an equivalent Typescript interface is not possible currently. For simple patterns there is something pretty close called template literal types.

With your particular question though patternProperties is not really your main issue. In fact, I would argue that given the schema:

         "styles": {
            "title": "Style Definitions",
            "description": "Style definition",
            "type": "object",
            "patternProperties": {
                "^.*$": {
                    ...
                }
            }
         }

That the following interface really is a good translation:

interface Styles {
    [key: string]: ...,
}

So despite the title of your question, your real question has to do with implementing oneOf functionality from json schema into a typescript interface. There is no "1 to 1" equivalent in TS, and the answer really becomes very specific to what the actual definitions are of Definition1 and Definition2. See this question.

Addendum:

The library I referenced, openapi-typescript, wrongly implements oneOf by using a TS union (relevant code). But as you observed, that is not correct. For example, the following is legal typescript:

interface First {
    aString: string;
    aNumber?: number;
}

interface Second {
    aString: string | boolean;
}

const tester: First | Second = {
    aString: 'asdgasdf'
}

console.log(tester);

but tester fulfills First AND Second, and so if this had been the jsonschema "equivalent" using oneOf, then tester would not have validated.

pooley1994
  • 723
  • 4
  • 16