Using Typescript to create a generic return type that is determined by the type of a property within an object union

Consider the following scenario:

type Setting = {
    key: "option_one",
    value: number,
} | {
    key: "option_two",
    value: string,
}

export type SettingKey = Setting["key"];
// "option_one"|"option_two"

How can we develop a function to handle this situation?

function getSettingValue(key: SettingKey) /* : return type based on key*/ {
    const setting: Setting = this.database.getSettingByKey(key);
    return setting.value;
}

When trying to assign a new object with the Setting type, TypeScript correctly identifies that assigning a string value when the key is option_one is an error.

const setting: Setting = {
    key: "option_one",
    value: "invalid input" // Error: Type 'string' is not assignable to type 'number'
};

Therefore, it should be possible to derive the specific data type of the value property inside the Setting object and utilize it as the return type for the function.

Is there a way to enforce the return type of the getSettingValue function to be determined by the provided SettingKey? Potentially utilizing generics rather than a generic number|string return type.

Answer №1

One possible solution is to utilize the Extract method in this scenario:

function retrieveConfig<K extends ConfigKey>(key: K): Extract<Config, { key: K }>["value"] {
  // Implementation goes here...
}

This function will filter out all elements in Config that match the criteria of being assignable to { key: K }, and then return the value type of those elements.

Link to 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

Guide on sending JSON object to Angular custom components

I have implemented a custom element in Angular 7 using the CUSTOM_ELEMENTS_SCHEMA. My app.module.ts code is as follows: export class AppModule { constructor(private injector: Injector) {} ngDoBootstrap() { this.registerCustomElements( ...

Unexpected behavior observed with Angular Toggle Button functionality

Having trouble implementing toggle functionality in Angular where different text is displayed when a button is toggled. I keep getting an error in my code, can anyone assist? See the code below: HTML <tr> <td>Otto</td> <td> ...

Exploring TypeScript and React Hooks for managing state and handling events

What are the different types of React.js's state and events? In the code snippet provided, I am currently using type: any as a workaround, but it feels like a hack. How can I properly define the types for them? When defining my custom hooks: If I u ...

Is it possible to enable typescript to build in watch mode with eslint integrated?

Can this be achieved without relying on webpack or other bundlers? Alternatively, is the only solution to have two separate consoles - one for building and another for linting? ...

How do I implement data range filtering in Typescript?

Seeking assistance with filtering data by date range and forwarding the results to the client. The objective is to extract tickets created within specific dates, but I keep encountering a console error which is proving challenging to resolve. var befor ...

Error: TypeError encountered during UI Runtime JSON conversion of Circular Data Structure

I'm facing an issue while attempting to parse and stringify certain JSON data. The error occurs on this specific line of code: this.copyOfColumns = JSON.parse(JSON.stringify(Object.assign([], this.columns))); Below is the complete @Input (using Ang ...

Issue with Ionic Capacitor React & Typescript build process for Firebase Functions

Recently, I've been working on a cutting-edge Ionic Capacitor React application that utilizes Typescript with a Firebase backend. While everything has been running smoothly so far, I encountered some challenges when trying to build Firebase Functions. ...

Angular StrictNullChecks: "Error - object may be null"

I am encountering an issue with the 'strictNullChecks' setting in my Angular project. This has resulted in numerous errors across my templates (.html), such as: <input #inputValue type="text" (keyup.ent ...

How to display an [object HTMLElement] using Angular

Imagine you have a dynamically created variable in HTML and you want to print it out with the new HTML syntax. However, you are unsure of how to do so. If you tried printing the variable directly in the HTML, it would simply display as text. This is the ...

Steps for modifying the look of a button to display an arrow upon being clicked with CSS

Looking to enhance the visual appearance of a button by having an arrow emerge from it upon clicking, all done through CSS. Currently developing a React application utilizing TypeScript. Upon clicking the next button, the arrow should transition from the ...

How should dynamic route pages be properly managed in NextJS?

Working on my first project using NextJS, I'm curious about the proper approach to managing dynamic routing. I've set up a http://localhost:3000/trips route that shows a page with a list of cards representing different "trips": https://i.stack. ...

Dealing with situations where an Angular component's route lacks a resolver

I have a component that handles both creating new items and updating existing ones. I have set up a Resolver for the 'edit/:id' route, but have not used one for the 'new' route. ngOnInit() { if (!(this.route.snapshot.url[0].path ...

The property you are trying to access is not found within the declared type of 'IntrinsicAttributes & { children?: ReactNode; }'

In my React project created using Create-React-App, I have included the following packages (relevant to the issue at hand): "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "^5.1.2", "react-scripts": "3.4.1", "typescript": "^3.9.2", "@typ ...

The Angular2 project using ag-grid-enterprise is currently experiencing difficulties with implementing the License Key

I have a valid license for the ag-grid-enterprise version, but I'm struggling with how to integrate it into my Angular2 project. I've attempted placing the license in the main.ts file using LicenseManager and specifying the enterprise version in ...

Sometimes, Express may return the message "not found" on and off

After working with express for many years, I find myself a bit out of practice with TypeScript - and it seems like my eyesight is failing me! This is the first time I've encountered this issue, so I must be missing something... My current dilemma is ...

Creation of Card Component with React Material-UI

I am facing difficulties in setting up the design for the card below. The media content is not loading and I cannot see any image on the card. Unfortunately, I am unable to share the original image due to company policies, so I have used a dummy image for ...

Jest's --findRelatedTests fails to identify associated test cases

Whenever I execute the command jest --bail --findRelatedTests src/components/BannerSet/BannerSet.tsx , an unexpected message is displayed: I couldn't locate any tests and hence exiting with code 1 If you want to exit with code 0 even when there are n ...

Combining multiple Observables and storing them in an array using TypeScript

I am working with two observables in my TypeScript code: The first observable is called ob_oj, and the second one is named ob_oj2. To combine these two observables, I use the following code: Observable.concat(ob_oj, ob_oj2).subscribe(res => { this.de ...

What is the best approach for managing Create/Edit pages in Next.js - should I fetch the product data in ServerSideProps or directly in the component?

Currently, I am working on a form that allows users to create a product. This form is equipped with react-hook-form to efficiently manage all the inputs. I am considering reusing this form for the Edit page since it shares the same fields, but the data wil ...

Experimenting with parallelism using TypeScript/JS

Currently, I am tackling a TS project that involves testing concurrent code and its interactions with a database, specifically focusing on idepotency. My goal is to ensure that multiple requests modifying the same resource will either apply changes correct ...