Tips for confirming the validity of JSON data using a Typescript interface from user input

I am facing an issue with validating an input field (text-area) that receives an array of objects in JSON format. The validation needs to be done at run-time based on an interface created in typescript.

Two interfaces Employee and Address were created with a custom type roleType

interface Employee {
  name: string;
  age: number;
  email: string;
  address?: Address;
  role?: roleType;
}

interface Address{
  city: string;
  pinCode: number;
}

type roleType = 'Developer' | 'UI Designer';

Sample valid JSON:

[
  {
    "name": "John Doe",
    "age": 25,
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aac0c5c2c4eacfc7cbc3c684c9c5c7">[email protected]</a>",
  },
  {
    "name": "Jane Doe",
    "age": 23,
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f99398979cb99c94989095d79a9694">[email protected]</a>",
  }
]

Sample invalid JSON:

[
  {
    "name": "John Doe",
    "age": 25,
    "language": "typescript",
  },
  {
    "name": "Jane Doe",
    "age": 23,
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fd979c9398bd98909c9491d39e9290">[email protected]</a>",
  }
]

Attempting to validate the array using a function checkArray with the following code:

function checkArray(array: any[]) {
  if (!Array.isArray(array)) {
    return false;
  }

  for (let i = 0; i < array.length; i++) {
    if (!(array[i] instanceof Employee)) {
      return false;
    }
  }

  return true;
}

However, this approach fails because interface Employee is a type and cannot be used as a value with instanceof operator.

I am seeking a way to validate my array with interface type and generate relevant errors without relying on external libraries. Any insights on how to achieve this?

Answer №1

Running TypeScript code at runtime is not possible because TypeScript is compiled to JavaScript. The use of the interface keyword is specific to TypeScript.

One alternative approach is to create a mapping of property names and their corresponding JavaScript typeof values.

interface Person {
  name: string;
  age: number;
  email: string;
  address: {
    city: string;
    country: string;
  }
  hobbies: string[];
}

type PersonValidationMap = Record<keyof Person, string> & { [key: string]: string};

const jsValidationMap: PersonValidationMap = {
  name: "string",
  age: "number",
  email: "string",
  address: "object",
  hobbies: "array"
}

const validatePerson = (person: Person) => {
  return Object.entries(person).map(([prop, value]) => {
    let passedValidation: boolean = false;
    if (jsValidationMap[prop] === "array") {
      passedValidation = Array.isArray(value);
    } else {
      passedValidation = typeof value === jsValidationMap[prop];
    }
    return { [prop]: passedValidation };
  })
}

const validPerson: Person = {
  name: "Alice",
  age: 30,
  email: "alice@example.com",
  address: {
    city: "New York",
    country: "USA"
  },
  hobbies: ["Reading", "Painting"]
}

const invalidPerson: Person = {
  name: "Bob",
  age: "Not a number" as any,
  email: "bob@example.com",
  address: undefined as any,
  hobbies: "Gardening" as any,
}

// Validating a valid person object
console.log(validatePerson(validPerson));

// Validating an invalid person object
console.log(validatePerson(invalidPerson));

Try this code on TS playground

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

When trying to implement an interface, the error message "Code lacks generality" and "^T cannot be generalized" is displayed in F#

Struggling to integrate the IJsonSerializer from Giraffe.Serialization.Json into a project along with Microsoft.FSharpLu.Json, encountering issues with a generic method (see code snippet below) type FSharpLuSerializer () = interface Giraffe.Serializat ...

Filtering Collections (Using List<String> in View and Controller Communication)

I am currently working on enhancing the search function for a collection I have, but I've hit a roadblock. I'm attempting to store a List in a hidden field within a form so that each time a user submits the form, I can add to it. Below is the co ...

The following 13 error occurred in the node_modules/next/dist/esm/server/web/spec-extension/cookies/serialize.js file

Every time I try to use the serialize function in my application on Next, it throws errors. Error - node_modules/next/dist/esm/server/web/spec-extension/cookies/serialize.js (40:0) @ parseCookieString Error - URI malformed I have attempted numerous soluti ...

Using AngularJS to send a large JSON file to a directive

It seems like I have identified the issue with the chart not displaying properly. The problem is most likely due to the fact that I am loading a large JSON object from a RESTful server and passing it to a directive for chart generation before the JSON has ...

Error encountered when dispatching action in ngOnInit: ExpressionChangedAfterItHasBeenCheckedError

I have set up my AppComponent to subscribe to the ngrx store in its constructor: export class AppComponent { submenuItems: Observable<Array<INavigationBarItem>>; constructor(private store: Store<AppState>) { this.submenu ...

I am looking to save a collection of variables in an array and store it as a $_SESSION variable

Looking to store an array of variables as a $_SESSION variable in order to use it in another .PHP file and perform operations with it. The array: <script> var idArray = [18, 28, 31, 38, 41]; </script> What I attempted, but didn't suc ...

What are the best ways to handle data using the .pipe() function?

Looking to optimize an Angular component Typescript function that returns an Observable<book[]>. The logic involves: If (data exists in sessionStorage) Then return it Else get it from remote API save it in sessionStorage return it End ...

Expectation in Observable: Unable to provide data retrieval

In my Angular 7 and Typescript project, I am faced with the challenge of reading a json file from within a zip file. Although I am able to successfully display the correct json output on the console, I am struggling to return this json data from the functi ...

Typescript monorepo facing issues with module resolution in Next.js projects

In my monorepo with yarn workspaces, I have 2 Next.js projects set up. apps ┣ app-1 ┗ app-2 The problem arises when app-1 needs to import components from app-2. I add app-2 as a dependency in the app-1 project and configure the path in app-1's ...

Ways to extract single JSON entities from a consolidated JSON structure

I am facing a challenge with parsing multiple JSON objects within a single large JSON object. Currently, the entire JSON object is being stored as one entity, but I need to parse and store them separately in MongoDB. Below is the code snippet I am using. ...

The type undefined cannot be assigned to the type even with a null check

When looking at my code, I encounter an error stating Argument of type 'Definition | undefined' is not assignable to parameter of type 'Definition'. Even though I am checking if the object value is not undefined with if (defs[type] != u ...

An error occurred suddenly while building: ReferenceError - the term "exports" is not defined in the ES module scope

Having trouble resolving this error in the Qwik framework while building a static site: ReferenceError: exports is not defined in ES module scope at file:///media/oem/MyFiles/8_DEVELOPMENT/nexasoft/server/@qwik-city-plan.mjs:1:1097 at ModuleJob. ...

organize information in a MySQL database in an array

Having some trouble formatting data pulled from my database and encoded into JSON using json_encode. I want to make it more readable in my android app by changing the format. Here is an example of the current encoded string at the bottom. Any suggestions w ...

When attempting to push `content[i]` into an array in AngularJS, it is flagged

In my JSON data, I have the following structure: var data = [{ id: 1, name: 'mobile', parentid: 0, limit:3 }, { id: 2, name: 'samsung', parentid: 1 }, { id: 3, name: 'moto', parenti ...

Discover the most efficient method for extracting specific information from a JSON file by utilizing the existing attributes

I've been tasked with creating a basic RESTful service in Go that retrieves data for a specific book based on its ID. type Book struct { ID string `json:"id"` Isbn string `json:"isbn"` Title string `json:"title"` Author *Aut ...

How to access specific values from a deserialized JSON string using Javascript

Within the nested for loops, I have the following row: document.getElementById("sm" + i + "b" + j).innerHTML = jsonval.values.sm1b1; ^^^^^^ In order to change the va ...

Storing a collection of integers within a nested data structure

Our team has implemented a custom serializer in C# to convert objects into JSON format for interacting with a REST API. The API requires data to be formatted like this: "product": { "sku": "211554", "extras": [{ "code": ...

The JSON retrieved from the API contains additional characters

Currently, I am dealing with an API that is quite old and unfortunately lacks sufficient documentation. Upon making a GET request on a specific route, the response returns JSON data along with additional characters at the beginning. This unexpected sequen ...

Error: The "res.json" method is not defined in CustomerComponent

FetchData(){ this.http.get("http://localhost:3000/Customers") .subscribe(data=>this.OnSuccess(data),data=>this.OnError(data)); } OnError(data:any){ console.debug(data.json()); } OnSuccess(data:any){ this.FetchData(); } SuccessGe ...

Exploring the power of EJS with conditional logic

Can someone help me figure out why EJS is not evaluating to the else branch in my code? I'm using EJS version 3.1.5 with express version 4.17.1 and typescript. ReferenceError: /home/pauld/tscript/dist/views/index.ejs:12 10| </head> 11| & ...