Creating TypeScript types that depend on the value of another property

Currently, I am in the process of formatting the HTTP PATCH document structure. I vaguely remember seeing conditional Typescript properties based on another prop value, but I cannot confirm. There might be a solution involving union types as well...

This is the schema:

[
 { "op": "test", "path": "/a/b/c", "value": "foo" },
 { "op": "remove", "path": "/a/b/c" },
 { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
 { "op": "replace", "path": "/a/b/c", "value": 42 },
 { "op": "move",, "from"": "/a/b/c", "path": "/a/b/d" },
 { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]

It's worth noting that there is an op property with possible values being

"test" | "remove" | "add" | "replace" | "move" | "copy"
. The move and copy operations include a
from<code> property without a <code>value
property like the others (except for remove) have.

While making from and value optional is a simple solution, it sacrifices validation. Therefore, I am exploring if defining types conforming to the schema is feasible, even if not straightforward.

Answer №1

You should explore union types, specifically discriminated unions.

type Schema =
  | { "op": "test", "path": string, "value": string }
  | { "op": "remove", "path": string }
  | { "op": "add", "path": string, "value": string[] } // value can be [string, string]
  | { "op": "replace", "path": string, "value": 42 }
  | { "op": "move", "from": string, "path": string }
  | { "op": "copy", "from": string, "path": string }


let o: Schema = { op: "move", from: "", path: "" }
let o2: Schema = { op: "remove", from: "", path: ""} // err

Playground Link

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

AngularJS is encountering issues with dependency injections when using WebStorm and TypeScript

A TypeScript AngularJS component: class MyComponentCtrl { static $inject = ['MyService']; constructor(private MyService) { MyService.testfn(55); // No error in typescript } } class MyComponent implements ng.IComponentOptions { ...

Guide to verifying the upcoming behavior subject data in Angular 8

I am facing an issue where I am attempting to access the next value of a BehaviorSubject in multiple components using a service. Although I can display the value in the UI using {{ interpolation }}, I am unable to see it in the console.log. Can someone hel ...

Create a keyup function that triggers an alert message if the user's input does not meet the

Hello, I'm looking for some assistance with a coding problem. Basically, I have an array of numbers which includes 5, 8, and 10. I need to create a form where users can input numbers. If the user inputs a number that is not 5, 8, or 10, I want to disp ...

Angular2 array sorting function is not functioning properly on mobile browsers

I'm currently working with a code snippet that looks like this: const words = ['apple', 'banana', 'zoom'] words.sort((first, second) => { const a = first; const b = second; return a == b ? 0 : a < b || a == ...

Transform Loopback 4 filter into a SQL WHERE condition

When using Loopback 4, the filter object that is received by functions like Get and Count appears as shown below: { where: { property: { op: value; } } } I am interested in converting this structure into an SQL WHERE clause to use it in ...

Traversing a sequence of method calls within a Promise object (as the return type)

In software development, there is a classic technique where a method returns the result of another method call: method1(): ObjectX { if( condition1 ) return method2(); return undefined // or some default value; } method2(): ObjectX { let r ...

Unable to locate module 'fs'

Hey there, I'm encountering an issue where the simplest Typescript Node.js setup isn't working for me. The error message I'm getting is TS2307: Cannot find module 'fs'. You can check out the question on Stack Overflow here. I&apos ...

What could be the reason for TypeScript throwing an error despite having a condition in place?

Having an issue with TypeScript (TS2531) and its non-null type checking. Here's the scenario: if (this.formGroup.get('inseeActivityCode') !== null) { mergedCompanyActivity.inseeActivityCode = this.formGroup.get('inseeActivityCode&ap ...

typescript set parameter conditionally within a function

For my upcoming app, I am working on an API that will utilize Firebase FCM Admin to send messages. Below is the code snippet: import type { NextApiRequest, NextApiResponse } from "next"; import { getMessaging } from "firebase-admin/messaging ...

Display a targeted highcharts tooltip using React and typescript

In my React project with TypeScript, I am looking to have the Highchart tooltip appear when the chart is initially displayed. Specifically, I want it to show at a certain point on the chart. I understand that I will need to utilize a load function for thi ...

Encountering an error when trying to declare a type in VSCode with ESlint and React Types

After setting up an axios configuration file with proper typing support, I encountered the following error message: import axios, { AxiosRequestConfig, AxiosInstance } from 'axios'; const api = axios.create({ baseURL: '/api', resp ...

Unable to determine model dependency in Nest

I encountered an issue where Nest is unable to resolve dependencies. The error message from the logger reads as follows: [Nest] 39472 - 17.08.2023, 05:45:34 ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserTransactionRepository ( ...

Tips for designing a custom TypeScript 5 property decorator

I have a decorator in TypeScript: const bindMethod = (method: any): PropertyDecorator => ((target: any, name?: PropertyKey): any => { if(name === undefined) { throw new Error('Bound decorator must be used with a property name.& ...

Issue encountered when working with interface and Observable during the http parsing process

Visual Studio File Structure Error app(folder) -->employee-list(folder) -->employee-list.component.html -->employee-list.component.ts -->app.component.html -->app.component.ts -->app.module.ts -->employee.json ...

Tips to successfully save and retrieve a state from storage

I've encountered a challenge while working on my Angular 14 and Ionic 6 app. I want to implement a "Welcome" screen that only appears the first time a user opens the app, and never again after that. I'm struggling to figure out how to save the s ...

Changing the selection on multiple input fields in Angular

I am working with two select elements in my form. Based on the selected value from the first select, I am filtering data for the second select. Additionally, I have an option to add the same row of form if desired. My issue is that when I select a value fr ...

Navigating through a dictionary in React TypescriptWould you like to learn

Currently, I am delving into the world of React and TypeScript. Within my journey, I have stumbled upon a dictionary representing various departments, with employee data stored in arrays. type Department = { Emp_Id: number, Name: string, Age: n ...

What is the best method for converting an Object with 4 properties to an Object with only 3 properties?

I have a pair of objects: The first one is a role object with the following properties: Role { roleId: string; name: string; description: string; isModerator: string; } role = { roleId:"8e8be141-130d-4e5c-82d2-0a642d4b73e1", ...

A service worker of unknown origin is currently getting registered

Currently, I am using the service worker provided in create-react-app. After registering it in index.tsx with serviceWorker.register();, everything seems to be working fine. However, upon closer inspection in the dev tools' Application tab, I noticed ...

When using the subscribe method in Angular4, I am encountering a null value for the data

After receiving data from my subscription and displaying it, I encounter an issue when calling my function as it returns a "null" value. I apologize for any language errors in my message. Thank you. this.service.prepareNewVersion().subscribe(data2 => ...