Modify a current type to create a new type by changing one property

Is it possible to convert an existing type into a new type with just one property change?

Typesctipt sandbox

For example:

type SomeComplexType = string // just for example

// cannot be changed
type Options<T> = {
    opt1: boolean | undefined;
    opt2: number;
    opt3?: SomeComplexType;
    opt4: T
}

// Can be changed

// How can we change opt1 to only accept true and infer other option types?
type Keys = keyof Options<any>

let r: { [K in Keys]: K extends 'opt1' ? true : any }

// Good (expected to work)
r = { opt1: true, opt2: 2, opt3: '1', opt4: 1 }
r = { opt1: true, opt2: 2, opt3: '1', opt4: 'str' }

// Bad (should result in error)
r = { opt1: false, opt2: 1, opt3: 'str', opt4: 1 } // opt1 should be true
r = { opt1: true, opt2: 'str', opt3: 'str', opt4: 1 } // opt2 should be a number
r = { opt1: true, opt2: 'str', opt3: 1, opt4: 1 } // opt3 should be 

Answer №1

Suppose you have an object type O and want to create a new type where all property keys and values are the same, except for the property at key opt1, which should be set to true. You can achieve this by using the following syntax:

{ [K in keyof O]: K extends 'opt1' ? true : O[K] }

The expression O[K] represents an indexed access, indicating "the type of the property of O with a key of type K".

With this approach, your examples should function as desired (assuming O is defined as Options<any>):

// Good 
r = { opt1: true, opt2: 2, opt3: '1', opt4: 1 } // okay
r = { opt1: true, opt2: 2, opt3: '1', opt4: 'str' } // okay

// Bad 
r = { opt1: false, opt2: 1, opt3: 'str', opt4: 1 } // error!
r = { opt1: true, opt2: 'str', opt3: 'str', opt4: 1 } // error!
r = { opt1: true, opt2: 'str', opt3: 1, opt4: 1 } // error!

Playground link to code

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

Struggling with generating a TypeScript declaration file

Struggling with creating a typescript definition file for a seemingly 'simple' npm module. Here are the key points: Problem: encounter an error when compiling TypeScript: play.ts(1,9): error TS2305: Module '"/to/the/dir/node_modules/geojs ...

Encountering the error message "Unable to access properties of null (specifically 'useState')" while trying to utilize a component from my custom library

After developing a personalized UI library and style guide to standardize components in my application, all was running smoothly until I incorporated a component utilizing the useState hook. An error consistently surfaces whenever I attempt to use a compo ...

Keep going in the for await loop in NodeJS

My code snippet looks like this: for await (const ele of offCycles) { if ((await MlQueueModel.find({ uuid: ele.uuid })).length !== 0) { continue; } <do something> } I'm curious if it's possible to use a continue st ...

Step-by-step guide on activating a button only when all form fields are validated

My very first Angular 5 project. I've gone through resources like: https://angular.io/guide/form-validation and various search results I looked up, only to realize that they are all outdated. In my form, I have several input fields such as: <for ...

The dropdown navigation bar fails to close upon being clicked

I'm currently facing an issue with the navbar in my project. The bootstrap navbar doesn't close automatically after clicking on a link. I have to move my mouse away from the navbar for it to close, which is not ideal. Additionally, I'm worki ...

Can type inference be utilized with the `forwardRef` method?

I am having an issue with the Type inference not working with the forwardRef in my component. I understand the reason behind this limitation, but I'm wondering if there is a workaround? https://i.sstatic.net/ZO3gI.png This is what I meant by type in ...

Learn how to capture complete stack traces for errors when using Google Cloud Functions

In the codebase I am currently working on, I came across a backend service that I would like to utilize for logging all errors along with their corresponding Http statuses. If possible, I also want to retrieve the full stack trace of these errors from this ...

What is the best way to incorporate an AJAX GET request into an HTML element?

Currently, I am attempting to execute a JavaScript code that will convert all <a></a> elements found within another element <b></b> (the specific name in the HTML) into links that trigger an HTTP get request. However, the code I hav ...

Dealing with nullable properties in Typescript

In my React Component code snippet, I am facing an issue with an optional field that needs to be initialized as undefined. This is causing difficulties when trying to use it after type checking. The problem arises in the context of using typescript version ...

Angular5/Karma is raising the error message "selector is not a recognized element"

I am encountering a small issue with my component. While everything seems to be working fine in my browser without any errors, the Karma debugger is throwing some errors that I would like to resolve for clarity. Error: Failed: Template parse errors: &apo ...

Automating button clicks after a component has loaded in Angular 2+ can be achieved by implementing a

Currently, I am working on implementing an automatic search function in Angular that triggers after a component loads. Right now, the function is triggered by a button click, but I want to automate this process. <button mat-raised-button class="mat-whi ...

Tips for utilizing single quotation marks while logging multiple variables in console

When I write console.log("entered values are "+A+" and "+B); the tsLint gives a warning that single quotes should be used. However, I discovered that if I use single quotes, I am unable to include multiple variables in the same console ...

Adapt the size of HTML video tags based on the width of the screen and level of

Within the site (developed with React, utilizing Typescript and Tailwind), there exists a component that allows users to watch videos (constructed using the HTML Video tag). Additionally, beneath the video, there are various dropdowns and buttons. However, ...

What is the reason for the prohibition of bitwise operators in tslint?

While we're unable to utilize bitwise operators in templates, what is the rationale behind tslint prohibiting their use within TypeScript code? "no-bitwise": true, ...

Managing numerous HTTP requests and providing the outcome through Angular and Rxjs

Currently, I am facing a challenge with sending GET requests for a large number of URLs (50 of them) to the Spotify server and then returning their results in a single Observable/array/object. This is the code snippet I have come up with: curatedTopArti ...

Issue with TypeScript createProgram due to undefined 'ts.sys' error

I am encountering an issue while trying to utilize the createProgram function. The error message states that ts.sys is undefined when running the following code: try { createProgram(Utils.getFileNames(), { lib: ['lib.es6.d.ts'] ...

Steps for exporting various elements from a .vue file

In my Vue project, I am incorporating TypeScript along with Vue. There is a specific scenario where I need to export multiple items from my .vue file. Here's an example of what I want to achieve: // FooBar.vue <template> ... </template& ...

Leverage one Injectable service within another Injectable service in Angular 5

I am facing difficulties in utilizing an Injectable service within another Injectable service in Angular 5. Below is my crudService.ts file: import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; ...

It is not possible to access an object's properties using bracket notation when the index is a variable

Is there a way to convert the JavaScript code below into TypeScript? function getProperties(obj) { for (let key in obj) { if (obj.hasOwnProperty(key)) { console.log(obj[key]); } } } I've been trying to find a solution but it seems t ...

Exploring the power of Vue 3 and Vuex with Typescript to access class methods

Can Vuex state be used to access class methods? For example, in this scenario, I am attempting to invoke fullName() to show the user's formatted name. TypeError: store.state.user.fullName is not a function Classes export class User { constructo ...