Ensuring a Generic Type in Typescript is a Subset of JSON: Best Practices

I am interested in achieving the following:

interface IJSON {
  [key: string]: string | number | boolean | IJSON |
                 string[] | number[] | boolean[] | IJSON[];
}

function iAcceptOnlyJSON<T subsetof IJSON>(json: T): T {
  return json;
}

let good = {
  message: 'it works',
};

let bad = {
  date: new Date(),
};

// Since good is a subset of IJSON, everything functions as expected!
iAcceptOnlyJSON(good);

// However, bad is not a subset of IJSON which should result in an error
iAcceptOnlyJSON(bad);

It's worth noting that there isn't a "subsetof" operator in Typescript. Is there a method to achieve this functionality in typescript?

Answer №1

You're almost there - the feature in the language is known as generic parameter constraints, and instead of using subsetof, you should use extends:

function onlyAcceptJSON<T extends IJSON>(json: T): T {
  return json;
}

The error message when calling onlyAcceptJSON(bad) says:

"Argument of type '{ date: Date; }' is not assignable to parameter of type 'IJSON'.
      Property 'date' is incompatible with index signature.
        Type 'Date' is not assignable to type 'string | number | boolean | IJSON | string[] | number[] | boolean[] | IJSON[]'.
          Type 'Date' is not assignable to type 'IJSON[]'.
              Property 'length' is missing in type 'Date'."

Although it's not foolproof - anything that's structurally compatible with a string, but isn't actually a string, will also pass.

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

Integrate child component properties within the parent component

Looking to create a wrapper component that selects specific props from an inner component and includes additional custom props. The issue is that using pick will generate a type rather than an interface, limiting the ability to add more keys. How can I wor ...

React error: Unexpected token < in JSON when fetching local file

I've encountered an issue with my React app. I have a JSON file in the public directory that I was successfully fetching data from in my main App.js file without any errors. However, after running `npm run build`, I started getting the error message: ...

Utilizing Typescript with Vue 3's Injection Feature

Using the new Vue 3 Composition API, I have created a "store" for reactive data. const state = reactive<State>({ accessToken: undefined, user: undefined, }); export default { state: readonly(state), } When my app is created, I pass the store ...

Transform a "flat" array into one that mimics a hierarchical directory structure

I am working with a collection of "directory objects" that have the following structure: $directoryObjects = [ [ 'type' => 'folder', 'name' => 'animals', 'path' => &apo ...

Inspect the TypeScript typings within Svelte documents directly from the terminal

When I run tsc --noemit, it successfully checks for type errors in the codebase. However, I have encountered an issue where it does not seem to check .svelte files. Is there a way to enable this functionality? I can see the type errors in .svelte files wh ...

Using JavaScript to analyze and handle newlines, spaces, and the backslash character

Hello everyone, I'm hoping things are going well. I am currently working on removing newline and "\" characters from a string that I have after using JSON.stringify(). The string in question appears as follows: "[{\n \"id_profile&bs ...

Problem with selecting items in Kendo UI Menu

Problem: The select event is not triggering when clicking on the image in the kendo menu item. My troubleshooting steps: Review the sample code provided below <!DOCTYPE html> <html> <head> <base href="http://demos.telerik.com/ken ...

What is the best way to specify Next.js Context types in TypeScript?

Can someone help me with defining the types for next js Context and req? Below is the code for the getServerSideProps function- //Server side functions export const getServerSideProps: GetServerSideProps = async (context) => { await getMovies(conte ...

C# The initialization process for 'Newtonsoft.Json.Serialization.DefaultSerializationBinder' encountered an error

My objective is to convert a JSON file into arrays in order to use them later within the C# script. However, I am facing difficulties as the JSON library refuses to load properly or when it does, I encounter errors regardless of how simple the JSON file is ...

Guide on incorporating the authorization function from next-auth into a TypeScript Next.js 13 app directory

Can you help me understand the proper way to declare the authorize function in [...nextauth].ts? I have been attempting it as shown below: export default NextAuth({ session: { strategy: "jwt" }, providers: ...

Mastering the Art of Utilizing Generic Typing to Access Objects

I am trying to find a way to access an object by class using generic typing. The issue I am encountering is that I am getting an error when trying to check if the locators contain an input field. type '{ form1: { item2: { checkbox: string; input: st ...

Converting SQL data into JSON object using PHP

I ran my PHP script and got the following result: { "user":{ "id":"1", "0":"1", "username":"test1", "1":"test1", "password":"pwd1", "2":"pwd1", "nom":"LUC", "3":"LUC", "prenom":"FOI", "4":"FOI ...

Set the array as the object attribute

Transitioning my app from AngularJs to Angular 4 has been quite a challenge. I've noticed that the type of statements I frequently used in my code are now failing in Angular 4 (TypeScript): Update: The following lines were previously used in Angular ...

"Unsuccessful API request leads to empty ngFor loop due to ngIf condition not being

I have been struggling to display the fetched data in my Angular 6 project. I have tried using ngIf and ngFor but nothing seems to work. My goal is to show data from movies on the HTML page, but for some reason, the data appears to be empty. Despite tryin ...

The Spring MVC controller is not designed to handle direct AJAX requests

In my server-side controller, I have the following method: @RequestMapping(value = {"/templates/test"}, method = RequestMethod.POST, consumes = "application/json") @ResponseBody public String TestURL(@RequestBody List<String> testString, ...

How to Efficiently Remove Array Elements by Index in Typescript

What is the best way to remove an item by its index using Typescript? For example: let myArray = ['apple', 'banana', 'cherry', 'date']; // How can I delete the item at index 2? ...

New options for outdated Webpack i18n plugin and loader

I am currently working on a TypeScript project that requires loading translations from individual .json files assigned to each country. For instance, we would have separate language files like en.json, es.json. The goal is to be able to access these trans ...

Trouble with choosing multiple values in Select2

I'm facing a challenge with my webpage that necessitates the use of the select2 component. The requirement is to display selected values upon loading as well. In my JavaScript file, I have two distinct constructs for this purpose. JavaScript - Constr ...

SonarQube flagging a suggestion to "eliminate this unnecessary assignment to a local variable"

Why am I encountering an error with SonarQube? How can I resolve it since the rule page does not offer a specific solution? The suggestion is to eliminate the unnecessary assignment to the local variable "validateAddressRequest". validateAddress() { ...

Encountering an issue on Safari: WeakMap variable not found in .NET Core 1.1.0 and Angular 2 application

I recently deployed a .NET Core 1.1.0 + Angular 2 + Typescript app on ASPHostPortal and encountered an issue while accessing it from Safari. The console showed the following exception: Can't find variable:WeakMap This caused the site to not load p ...