What is the best way to define a property that only exists under certain conditions?

After the server responds, it will look like this:

{
    code: number;
    info: string;
    data //appears only when code is 200
}

How can I create a type definition to specify that the data property should only exist when code is 200?

My current code implementation looks like this:

const res = await fetch(...)
const result:MyType = await res.json()
if (result.code != 200) {
   //handle case with no data 
} else {
  //handle data in result.data
}

Github copilot suggests the following solution, which seems to be functional. However, I'm curious if there are alternative approaches.

type Type1 = {
    code: number;
    info: string;
    data?: string; // Optional property
}

type Type2 = Type1 & { code: 200, data: string };

// Usage:
const obj1: Type2 = { code: 200, info: "Success" }; // Error: 'data' property is missing, but obj1 can be set as Type1
const obj2: Type1 = { code: 404, info: "Not Found" }; // Valid
const obj3: Type2 = { code: 200, info: "Success", data: "Some data" }; // Valid 
 

Answer №1

Upon reflecting on the insights shared by @jcalz (his demonstration enlightened me about type predicates) and delving into the answer provided in Understanding the functionality of the `is` keyword in typescript?, particularly case #3 where there is no compile error but a runtime error.

Given the necessity to perform a runtime check for data (since ts narrowing does not completely eliminate this need), I have devised a satisfactory solution for my use case.

interface MyType {
    code: number,
    info: string,
    data: string | null //null value indicates code != 200
}

const res = await fetch(...)
const result:MyType = await res.json()
if (result.code != 200 || !result.data) {
   //handle scenario with no data 
} else {
  //process result.data
}

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

Can you explain the purpose of the `never[]` parameter type as defined in the TypeScript Handbook?

Exploring the topic of Inferring Within Conditional Types, an illustrative example is provided: type GetReturnType<Type> = Type extends (...args: never[]) => infer Return ? Return : never; type Num = GetReturnType<() => number>; type ...

Unexpected issue occurred in Angular 16 when utilizing less compiler. Error message displayed: "URL token should be closed with a ')'."

I'm having trouble locating the missing parenthesis. It seems like the issue may not be in this file. Any suggestions on how to troubleshoot this? I've already disabled optimization "optimization": false ./src/main.ts - Error: Mod ...

Tips for managing errors when using .listen() in Express with Typescript

Currently in the process of transitioning my project to use Typescript. Previously, my code for launching Express in Node looked like this: server.listen(port, (error) => { if (error) throw error; console.info(`Ready on port ${port}`); }); However ...

The @output decorator in Angular5 enables communication between child and

Hello fellow learners, I am currently diving into the world of Angular and recently stumbled upon the @output decorators in angular. Despite my best efforts to research the topic, I find myself struggling to fully grasp this concept. Here's a snippet ...

Monitoring the loading progress of multiple files using Three JS

Just starting out with Three JS and I'm on a mission to create a loading screen that displays the progress of assets being loaded for a scene. I have a total of 7 different types of assets, including: 4 GLB files 2 Texture files And 1 Obj file Acco ...

Creating a Fixed HeaderToolbar in FullCalendar React

I am currently working on customizing the FullCalendar React component and I am looking to incorporate a sticky headerToolbar. My main objective is to have the header along with its toolbar remain fixed at the top of the calendar, even when users scroll th ...

What is the best way to include TypeScript definition files in version control?

I am working on a basic asp.net core web application and have integrated javascript libraries using libman. Now, I am looking to incorporate typescript, therefore I have obtained typescript definition files for the libraries via npm. For example: npm ins ...

Unable to locate module src/ in Node.js TypeScript

I'm encountering issues with non-relative imports in my node.js / typescript application. Here is my tsconfig: { "compilerOptions": { "target": "es6", "module": "commonjs", "lib": ["dom", "es6", "es2017", "esnext.asynciterable"], "s ...

Discover the highest value within an array of objects, along with any numerical object attributes that have a value greater than zero

Considering an array of objects structured as follows: [{ "202201": { "WO": 900, "WS": 0, "SY": 0.915, "LY": 0.98, "CT": 75 }, "202202" ...

Developing various VueJS TypeScript projects utilizing a shared library

In the process of developing two VueJS applications using TypeScript, I have created one for public use and another as an admin tool exclusively for my own use. Both applications are being built and tested using vue-cli with a simple npm run serve command. ...

typescriptIs there a more efficient approach to typing optional values without a default value in

In my React application with TypeScript, I am using the following code to provide typed props: type ScheduleBoxContentProps = { desc: ReactNode, lottie: LottieProps, } & Partial<{className: string}>; I want the className prop to be optional ...

What is the process for setting up a single button selection using OR logic and multiple button selection using AND logic?

Currently working on implementing button functionality in React for filtering data. The requirement is that when selecting specific criteria, such as bedroom 3 or multiple selections like bedroom 2 and 3, the logic should vary. For instance, selecting bedr ...

NodeJS can be used to convert JSON data into an XLSX file format and allow for

I am currently working on a project in nodejs where I need to convert JSON data into XLSX format and then download it to the client's browser. I have been using the XLSX npm module to successfully convert the JSON data into a Workbook, however, I am f ...

Is it possible to specify a key on an object while allowing TypeScript to infer the value's type automatically?

Currently, I am working on a challenge where I aim to establish specific keys for an object while allowing TypeScript to infer the types of the values. Here is a simple example: const fooVals = { a: null, b: null, c: null, e: null, } type TfooV ...

Each row in a table is filled with an array of data, with each column containing pdf

My goal is to split each associated element in every row of my PDF. Currently, the values are displayed below each column, as shown in the image below. packStruct = [] packEnergy = [] packDescriptionEnergy = [] packPrice = [] {text: 'Integration&apos ...

Decorators in Angular 9 do not have the capability to support function expressions

Currently, I am working with Angular 9 and facing an issue while generating dynamic routes values during runtime. I have implemented a ComplexUrlRouter to achieve this functionality and integrated it into my Route configuration. However, I encountered the ...

Guide to sending a HTTP POST request with parameters in typescript

I need assistance sending a POST request using parameters in the following format: http://127.0.0.1:9000/api?command={"command":"value","params":{"key":"value","key":"value","key":"value","key":value,}} I attempted to do this but encountered an issue: l ...

The Radio Button's value appears in a distinct way on Ionic Angular

I am currently working with the Ionic framework and I am trying to display data values on radio buttons. However, I am facing difficulties in retrieving the correct value and setting it appropriately. index.html <td> <label>{{learn ...

Trouble with launching Jasmine tests within define block in compiled Typescript

Currently, I am immersed in a testing project that involves setting up a pure Javascript Jasmine Karma environment to test a pre-compiled Typescript setup. Despite my efforts, I am facing an issue where the test cases refuse to start running. While the co ...

Encountering a Lint error stating "Expected 2 arguments, but received 1" during the testing of the window.scrollBy() function in Jasmine following an Angular

During the upgrade to Angular 11, several other packages, such as jasmine-core, were also upgraded. This caused lint issues when running the 'npm run test' command due to stricter type definitions. One specific issue involves the window.scrollBy ...