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