Is there a way to specify patternProperties in a JSON schema and then map it to a TypeScript interface?

I'm in the process of developing a TypeScript interface that corresponds to a JSON schema. The specific field in my JSON schema is as follows:

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

My initial idea for the interface was:

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

Unfortunately, this approach doesn't fully capture the intended meaning of the JSON schema. I'm seeking guidance on how to properly structure this in my TypeScript interface.

Any suggestions on how I should tackle this?

Answer №1

I encountered the same issue when trying to convert schemas using patternProperties into TypeScript interfaces with the hope that the openapi-typescript library would handle it, but it seems the support is not available at the moment. (Refer to the issue I raised).

The challenge with patternProperties essentially revolves around whether we can constrain a string in TypeScript to only accept values that match a particular regex pattern. You can find an explanation here. To summarize, regular expression constraints are not directly supported (although there is an ongoing proposal for this feature), indicating that converting schemas utilizing patternProperties to corresponding TypeScript interfaces is currently unachievable generically. For simpler patterns, a similar concept called template literal types exists.

In your specific scenario, however, your primary concern is not really about patternProperties. In fact, given the provided schema:

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

The suggested interface actually serves as an effective translation:

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

Thus, despite the title of your query, the actual conundrum pertains to integrating oneOf functionality from JSON schema into a TypeScript interface. There is no direct equivalent in TS, and the solution varies based on the definitions of Definition1 and Definition2. Refer to this question.

Addendum:

The misuse of oneOf by openapi-typescript library through a TS union (relevant code) has been noted. As showcased, the following TypeScript snippet is valid:

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

interface Second {
    aString: string | boolean;
}

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

console.log(tester);

However, since tester satisfies both First and Second, if this were to be the JSON schema "equivalent" using oneOf, then tester would fail validation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging TypeScript alongside body-parser to access properties within req.body

I'm currently developing a web application using TypeScript and integrating the body-parser middleware to handle JSON request bodies. I've encountered type errors while attempting to access properties on the Request.body object. For instance, wh ...

How to effectively utilize TypeScript in a team environment using both Atom and VSCode?

Our team utilizes TypeScript with both Atom and VSCode as our editors, but we are facing challenges with the tsconfig.json file. VSCode is not recognizing the typings, causing the namespace for 'ng' (for Angular 1.x) to be unknown in VSCode. Wh ...

What is the best way to export a file in scrapy while only specifying the path?

Currently utilizing Scrapy, I am in the process of exporting files. One dilemma I am facing is with specifying the file path. Although using FEED_URI has been effective, it only allows for the name of the file to be included. FEED_URI = 'file:///C:/Us ...

Error message displayed when searching in DataTables due to invalid JSON input

I have been working on integrating DataTables with PHP and MySQL for server-side processing, following the guide provided here. Although I'm able to display data correctly, whenever I attempt to use the search bar or filters, I encounter the following ...

Extracting data from the response object and injecting it into the request

Once the file has been successfully uploaded, the 'uploadSuccess' callback event is triggered, providing information about the newly created media. The 'hashed_id' value within this object is crucial for my PUT request. I attempted to ...

Delivering secure route information to paths in Angular 2

When defining my routes in the routing module, I have structured the data passing like this: const routes: Routes = [ { path: '', redirectTo: 'login', pathMatch: 'full' }, { path: 'login', component: LoginCompon ...

Converting JSON data to an array using an Ajax request

I am currently working on an HTML project where I have the following code: <div id="main"> <div id="blogcont"> <p></p> </div> <button class="nvgt" id="prev" >Previous</button> <button ...

Unveiling typescript property guards for the unknown data type

Is there a way to type guard an unknown type in TypeScript? const foo = (obj: unknown) => { if (typeof obj === 'object' && obj) { if ('foo' in obj && typeof obj.foo === 'string') { r ...

Issue TS2322: The type 'Observable<any>' cannot be matched with type 'NgIterable<any> | null | undefined'

Encountering an error while attempting to fetch data from the API. See the error image here. export class UserService { baseurl: string = "https://jsonplaceholder.typicode.com/"; constructor(private http: HttpClient) { } listUsers(){ //this ...

encountering issues with configuring TypeScript LSP in NeoVim with the use of the lazy package manager

Encountered an error in nvim when opening a .ts file. Using mason, mason-lspconfig, and nvim-lspconfig for lsp setup. Lua language lsp is functioning properly, but facing errors with ts files as shown in the screenshot below: https://i.stack.imgur.com/gYM ...

An error message was returned when trying to decode the array using json

I have a PHP program that accesses a .txt file and decodes the JSON to insert the user's email and name data into my campaign monitor database. The JSON format is strange because new entries use a ][ sequence as shown in this example: [{"email":"< ...

Utilizing nested jasper subreports with a JSON data source

I am facing a challenge with my json datasource that contains arrays within arrays. I am currently using subreports in my project, where the datasource is derived from the master datasource using datasourceExpression and the 'subdata()' method. ...

Transform the date format in react.js using information provided by an API endpoint

I'm currently working on a project using React and TypeScript where I need to format the date retrieved from an API. I am able to map over the data and display it, but I'm struggling to convert it into a format like '22 June 2021'. The ...

I'm trying to figure out how to incorporate types for utilizing Intl.ListFormat in node v12. Can

I am currently working with nodeJS version 12.10.0, which now includes support for Intl.ListFormat. I am also using Typescript version 3.6.3. However, when compiling my code with Typescript, I encounter the following error: Property 'ListFormat' ...

Exploring techniques to iterate through this specific JSON data within an Angular frontend

I am looking for assistance in looping the data below into a 'Select dropdown' using Angular 10. The data consists of all the States in India along with their districts. I have retrieved this information from the internet, but I am unsure how to ...

Exploring JSON parsing in Perl

There is a json stored in a file named sample.txt I am interested in decoding the entire json and extracting key values by specifying them. Below is an example of my code: #!/usr/bin/perl use JSON; use Data::Dumper; use JSON::XS qw( decode_json ); ope ...

Transform an angular1 javascript circular queue implementation for calculating rolling averages into typescript

I am currently in the process of migrating a project from Angular 1 to Angular 2. One of the key components is a chart that displays a moving average line, which requires the use of a circular queue with prototype methods like add, remove, and getAverage. ...

Seeking a quick conversion method for transforming x or x[] into x[] in a single line of code

Is there a concise TypeScript one-liner that can replace the arrayOrMemberToArray function below? function arrayOrMemberToArray<T>(input: T | T[]): T[] { if(Arrary.isArray(input)) return input return [input] } Trying to cram this logic into a te ...

Retrieving the value of a selected option in Angular

I have the following dropdown select in my HTML and I am currently retrieving the text content of the selected option. How can I access the value attribute instead? Here is the dropdown select: <form [formGroup]="angForm" class="form-inline my-5 my-l ...

How can I dynamically insert various FormGroup instances into a FormArray in Angular?

I am looking to dynamically populate the order array with multiple dishes. Each dish will be stored as a FormGroup in the form, such as pizza, salad, drink, or any other type of dish. Prior to adding any items, the form structure should resemble this: this ...