How can you designate an object property as optional based on a condition in Typescript?

For example:

type Example = {
    'x': string,
    'y': null,
};

type Test<T extends keyof Example> = {
    prop: Example[T],
};

const test1: Test<'x'> = { prop: 'x' }; // success
const test2: Test<'y'> = { prop: null }; // success
const test3: Test<'z'> = {}; // Property 'prop' is missing in type '{}' but required in type 'Test<"z">'.

TS Playground: https://www.typescriptlang.org/play?#code/C4TwDgpgBAYg9nKBeKBvAUFLUDkBDHALigGdgAnASwDsBzAGk2xwCMioBXagEwgDMaEbowC+AbnTpQkKACE85ADwAVKBAAewCDxJQA13TC8AjAPlUaMAFAOsVB50AL7+BUhABKctWAjRPLApBEwfLEF6fRmOIAFXFSMoSsohdnlwIACIxksbFUhbKZthYXQoKmytziMmlKTgsEvcyNDFrswEMlcobFxAA

In this scenario, I want the prop property to be optional when its value is null. Essentially, I would like { prop: null } and {} to have the same meaning.

In my practical application, I am dealing with API handlers that may return different data fields based on conditions. If a field is unnecessary, I prefer to exclude it rather than defining it as null.

One potential solution is:

type Test<T extends keyof Example> = Example[T] extends null
  ? { prop?: null }
  : { prop: Example[T] };

However, if many fields need to be optional, this conditional statement can grow quite lengthy. Is there a more efficient approach?

Answer №1

type Cat = {
    'x': string,
    'y': undefined,
}

type Dog<U extends keyof Cat> = {
    propertyOne: Cat[U],
    propertyTwo: Cat[U]
};

type UndefinedDogKeys<U extends keyof Cat> = {
  [Z in keyof Dog<U>]: Dog<U>[Z] extends undefined ? Z : never 
}[keyof Dog<U>];

type BestDog<U extends keyof Cat> =
    Cat[U] extends undefined
    ? { [Z in keyof Pick<Dog<U>, UndefinedDogKeys<U>>]?: Cat[U] }
    : Dog<U>;

const dog1: BestDog<'x'> = { propertyOne: 'meow', propertyTwo: 'woof'};
const dog2: BestDog<'y'> = { propertyOne: undefined, propertyTwo: undefined };
const dog3: BestDog<'y'> = {};

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

Lambda function failing to execute Auth0 methods through the Auth0 node-auth0 SDK

I am working with a lambda function that triggers when a message is added to the SQS queue. Within the message, there is a userId that I want to connect to using the Auth0 node SDK. The code snippet for my GetUserDetails function below shows that it logs ...

Adjust the Placement of Images in Relation to Mouse Movements

Is there a way to creatively animate the positions of images or background images based on mouse movement? Let's take Github, for instance: https://github.com/thispagedoesntexist The 404 page on Github is truly impressive. I aim to captivate my use ...

The login form using ajax is malfunctioning

I am struggling to retrieve user information from a MySQL database and display it on the webpage when the user logs in. However, I'm encountering some issues with the logic. When incorrect email or password is entered, an error message is displayed bu ...

I am noticing that my popover is causing my page to shift when I click it. It is expanding the width of my page more than I would

Upon clicking the user id popover on my page, it expands the page width instead of adjusting within the page boundaries. This is the issue: https://i.stack.imgur.com/EqaMo.png There's a small white space present that I want to eliminate. When the po ...

Issue with applying value changes in Timeout on Angular Material components

I'm currently experimenting with Angular, and I seem to be struggling with displaying a fake progress bar using the "angular/material/progress-bar" component. (https://material.angular.io/components/progress-bar/) In my "app.component.html", I have m ...

How can I showcase the captured image on Ionic 2?

I am having trouble displaying the selected or captured image on the page after uploading it through two methods - one using the gallery and the other using the camera. ** Here is my code ** 1) profile.html: <img class="profile-picture" src="{{baseUr ...

Tips for effectively typing an object with a variety of value types

Greetings and thank you for your help in advance. I am currently working on creating a UI component that accepts boolean and string style props. However, I encountered an error related to the Styles type which includes the bg prop that accepts a string. I ...

JavaScript code that retrieves the current exchange rate of Bitcoin (BTC)

Seeking to create a JavaScript function that returns the current exchange rate for BTC/USD. Keeping it simple without using server-side calculations, just a user-friendly feature. I have 2 text fields and want one value to update automatically when the oth ...

Comprehend the angular and in a confined scope and its brackets

I have been wondering why I have to use double brackets ()() when passing a method from an outer scope to a directive with an isolated scope using '&'. It seems like the function is returned with callThat() and then I need to call it with anothe ...

Experiencing some unusual shadows in my Three.js project while attempting to add a simple shadow effect to a cube or group of cubes

Trying my hand at implementing shadows in Three.js, even though I am fairly new to JavaScript. My attempts to create a cube with a proper shadow have yielded partial results, as only a portion of the mesh seems to be casting the shadow. https://i.sstatic. ...

Passing Multiple GET Parameters in PHP Using Ajax

Currently, I am utilizing a set of buttons to filter a table of data in my project. Two buttons are functioning well with the code snippet below: <button onclick="filter('open');" class="open">Open</button> <button onclick="filte ...

Javascript Issue: Difficulty Implementing Item List Container

Is there a way to adjust the list so that it only expands the container from the bottom, causing a scrollbar to appear? LINK TO CODE EXAMPLE: https://codepen.io/Redd_1/pen/qBZWJQG ...

Asynchronous function failing to pause execution at await

My async functions are causing issues after recently switching from Mocha to Jest. Previously, my code would await the import of a JSON file and then manipulate the data sequentially. However, since the migration, all my tests and functions are breaking. ...

What causes the sudden disappearance of the returned value from AJAX?

This piece of code is what runs on my server: modify_emp.php <?php echo $_POST[id]; ?> Below is the Javascript code in my HTML page: <script> $(document).ready(function () { var alreadyClicked = false; $('.element').h ...

Issue connecting to new primary replica set in MongoDB

Struggling with the setup of MongoDB for my Node.JS application. I keep running this command: mongo "mongodb+srv://cluster0-gjc2u.mongodb.net/test" --username <myusername> However, every time I attempt it, I receive the following response. MongoD ...

Avoid retrieving data during the fetching process

I have been working on an application that utilizes Redux for state management. Furthermore, I have been using the native fetch method to fetch data. return fetch("https://dog.ceo/api/breeds/image/random").then(res => res.json()); Within my React co ...

The 'else' statement does not seem to function properly with the 'src' attribute

I have been attempting to include alt text in a web page using jQuery with the code below. However, I am only able to get the correct value for the first image. The else if and else conditions do not seem to be working properly as I am unable to add alt ...

You must provide a secret or key in order to use the JwtStrategy

I have encountered the following error and I am unsure of its cause. Can you assist me? ERROR [ExceptionHandler] JwtStrategy requires a secret or key TypeError: JwtStrategy requires a secret or key at new JwtStrategy (C:\Users\wapg2\OneDriv ...

Using a custom module in node.js to retrieve data from a mysql database

How can I retrieve select query results? I am currently getting empty or null responses. Despite attempting callback logic and using the callback function as suggested in some articles, I have yet to have any success. All of the code for my Custom Module ...

Invoke a JavaScript function from an external script while passing a parameter upon the loading of a webpage

I am still new to JavaScript, so I was wondering if there is a way to achieve the following: main.js: $(function () { $('.delete_btn').click(function () { var confirmation = confirm('Do you want to remove this event?'); ...