Tips on modifying the selected type key name through Pick?

I currently have this structure:

type Product = {
  name: string
}

and I am looking to extract the name property and use it in a different type declaration like so:

type NewProduct = Pick<Product, 'name'>

Now, I want to rename name as newName within the NewProduct type. How can this be accomplished?

Answer №1

Using a mapped type utility allows you to easily rename selected properties. Consider the following example:

type RenameAndPick<T, PropMap extends Partial<Record<keyof T, string>>> = {
  [
    K in keyof PropMap as K extends keyof T
      ? PropMap[K] extends string
        ? PropMap[K]
        : never
      : never
  ]: K extends keyof T ? T[K] : never;
};

When applied with the specifics from your query:

type Data = {
  name: string;
};

type NewData = RenameAndPick<Data, { name: 'newName' }>;

The resulting type would be:

type NewData = {
  newName: string;
};

A key benefit of using this type utility is the ability to select and rename multiple properties (similar to Pick<Type, Keys>) while retaining a consistent syntax. For instance:

type UserDetails = {
  age: number;
  firstName: string;
  lastName: string;
};

type NewUserDetails = RenameAndPick<UserDetails, {
  firstName: 'first';
  lastName: 'last';
}>;

/* Output:

type NewUserDetails = {
  first: string;
  last: string;
};

*/

This utility also handles cases where invalid properties are picked:

type NewUserDetails2 = RenameAndPick<UserDetails, {
  firstName: 'first';
  age: 'userAge';
  somePropNotPresent: 'newName';
}>;

/* Output:

type NewUserDetails2 = {
  first: string;
  userAge: number;
};

*/

Code in TS Playground

Answer №2

Forget about using Pick. Here's a better way:

type Item = {
  title: string
};

type NewItem = {
    newTitle: Item["title"];
};

Check out the Playground!

Answer №3

Given this simple scenario, @caTS provides the superior solution. However, it is important to note that in more complex situations, the types may be more intricate.


If you need to dramatically change a single property, a type operation such as the following might be more suitable:

Omit<T, K> & { [newKey in K]: NewTypeHere }

This approach allows you to create a type that can rename a property like this:

type RenameProp<T, K1 extends keyof T, K2 extends string> =
    Omit<T, K1> & { [newKey in K2]: T[K1] }

You would implement it as follows:

type Item = {
  title: string
  content: string
}

type NewItem = RenameProp<Item, 'title', 'newTitle'>
const newItem: NewItem = { newTitle: 'testing', content: 'abc123' } // works fine

View 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

Typescript is failing to compile classes in a reliable sequential order

In my MVC 5 project, I am using TypeScript and angular. There are three TS files: Controller1.ts, Controller2.ts, and app.ts. The issue arises when I compile the program for the first time - everything usually compiles correctly in the expected order. Howe ...

Is it advisable to avoid circular imports in typescript development?

After spending 4 long hours troubleshooting a TypeScript error, I finally found the root cause. Object literal may only specify known properties, and 'details' does not exist in type 'Readonly<{ [x: `details.${string}.value`]: { value: st ...

During the present module, retrieve the runtime list of all modules that are directly imported (Javascript/Typescript)

Imagine you have a set of modules imported in the current module: import {A1, A2, A3} from "./ModuleA"; import {B1, B2, B3} from "./ModuleB"; import {C1, C2, C3} from "./ModuleC"; function retrieveListOfImportedModules() { // ...

Pause and anticipate the subscription within the corresponding function

Is there a way to make an If-Else branch wait for all REST calls to finish, even if the Else side has no REST calls? Let's take a look at this scenario: createNewList(oldList: any[]) { const newList = []; oldList.forEach(element => { if (eleme ...

Is a package.json file missing dependencies?

Curious about the meaning of peerDependencies, I examined the contents of this package.json file. It relates to a library project that is distributed elsewhere. { "name": "...", "version": "...", "description": "...", "author": "...", ...

Accelerated repository uses TypeScript to compile a node application with dependencies managed within a shared workspace

Struggling to set up an express api within a pnpm turborepo workspace. The api relies on @my/shared as a dependency, which is a local workspace package. I have been facing challenges in getting the build process right. It seems like I need to build the s ...

Building a personalized React component poses challenges when working with MUI REACT interfaces

I am looking to develop a unique component that will display two different elements, an icon, and a title. However, I seem to be encountering errors from TypeScript regarding the declaration of my interface. The error message reads: Property 'map&apos ...

Troubleshooting a Type Parameter Error in React Native TypeScript

I am working on a project in React Native using TypeScript, and I encountered this issue: I am getting the error Argument of type 'GestureResponderEvent' is not assignable to parameter of type 'SetStateAction<string>'.ts(2345) wit ...

Issues arise in Typescript single-page applications due to the use of application insights

Currently, I am developing a single-page HTML application using TypeScript in VSCode. Initially, the app was running smoothly without any errors or warnings. However, I decided to incorporate Azure Application Insight into the project. To integrate it, I ...

What is the best way to compare two TypeScript object arrays for equality, especially when some objects may have multiple ways to be considered equivalent

Currently, I am in the process of developing a cost function for a game where players are given a set of resources in their hand. The resources can be categorized into different types such as Fire, Air, Water, Earth, Good, Evil, Law, Chaos, and Void. Thes ...

The combination of Autodesk Forge Viewer and React with TypeScript provides a powerful platform for developing

I'm brand new to React and Typescript, and I have a very basic question. In the viewer documentation, extensions are defined as classes. Is it possible to transform that class into a typescript function? Does that even make sense? For example, take th ...

Is it possible to utilize the inline/hardcoded type declared in the component.d.ts file for reuse

Is there a way to pass props selectively to the library component? The library has hardcoded multiple values in an inline type. If my code needs to automatically update with any new additions to the library-defined type, can I reuse those inline values r ...

Can you explain how to utilize multiple spread props within a React component?

I'm currently working in TypeScript and I have a situation where I need to pass two objects as props to my React component. Through my research, I found out that I can do this by writing: <MyComponent {...obj1} {...obj2} /> However, I'm fa ...

The altered closure variable ts remains undetectable

Check out the live demonstration I made changes to the flag variable, but TypeScript did not recognize it. Could this be a coding issue? function fn () { let flag = true function f () { // alter the value of flag flag = false } for (let ...

The 'any' type is automatically assigned to Angular and Element since the type 'IData' lacks an index signature

Looking to display specific object properties based on predefined keys in an array? Here's an example using TypeScript: const dataObject: IData = { a: 1, b: 2, c: 3 }; const dataKeys: string[] = ['a', 'c']; dataKeys.forEach((key: ...

angular2 the custom template validator is encountering outdated values

I've been struggling with a specific issue for quite some time now. I'm working on setting up an Angular 2 custom validator that checks if a number falls within a certain range. When used as follows, everything functions correctly: <input typ ...

The lite-server is not compatible for initiating the Angular2 Quickstart

Struggling to get the Angular2 Quick start app up and running on my Windows system. Unfortunately, I've hit a roadblock with the "lite-server". Despite installing dependencies (npm install), when attempting to run the app (npm start), an error pops u ...

The external typing file encounters an issue when trying to locate the relative path to its own index.d.ts file

While working on my project and using react-color as a dependency, I encountered an issue with the tsc import failing. The error message displayed: node_modules/@types/react-color/lib/components/sketch/Sketch.d.ts(2,41): error TS2307: Cannot find module & ...

Is there a way to incorporate new members into a pre-existing type in TypeScript?

While examining the definition file for the commander project, one can observe the following interface being utilized: interface IExportedCommand extends ICommand { Command: commander.ICommandStatic; Option: commander.IOptionStatic; [key: stri ...

Typescript's default string types offer a versatile approach to defining string values

Here is an example code snippet to consider: type PredefinedStrings = 'test' | 'otherTest'; interface MyObject { type: string | PredefinedStrings; } The interface MyObject has a single property called type, which can be one of the ...