There is no built-in type for a renaming Pick
, fortunately we can create one with reasonable effort.
Simple variant
type IdRenamed = Omit<User, "_id"> & { id: User["_id"] }
// { name: string; email: string; password: string; phone: number; id: string;}
Playground
Dynamic version for single property
type PickRename<T, K extends keyof T, R extends PropertyKey> =
Omit<T, K> & { [P in R]: T[K] }
type T21 = PickRename<User, "_id", "id"> // same type as above
type T22 = PickRename<User, "foo", "id"> // error, foo is no property
Playground
TS 4.1 Alternative: use mapped type as
clauses. Its advantage is that readonly
or optional (?
) modifiers of properties are preserved (see homomorphic mapped types 1, 2 for more details).
type PickRename<T, K extends keyof T, R extends PropertyKey> = {
[P in keyof T as P extends K ? R : P]: T[P]
} // type instantiation same as previous example
Playground
Dynamic version for multiple properties
type PickRenameMulti<T, R extends
{ [K in keyof R]: K extends keyof T ? PropertyKey : "Error: key not in T" }
> = Omit<T, keyof R> & UnionToIntersection<
{ [P in keyof R & keyof T]: { [PP in R[P]]: T[P] } }[keyof R & keyof T]
>
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends
((k: infer I) => void) ? I : never
type T31 = PickRenameMulti<User, { _id: "id"; name: "firstName" }>
type T32 = PickRenameMulti<User, { foo: "id" }> // error, foo is no property
Note: See the great UnionToIntersection
type for more details on the helper.
Playground
type PickRenameMulti<T, R extends
{ [K in keyof R]: K extends keyof T ? PropertyKey : "Error: key not in T" }
> = { [P in keyof T as P extends keyof R ? R[P] : P]: T[P] }
Playground
TS 4.1: Drop _
prefix from all property keys
type DropUnderscore<T> = {
[K in keyof T as K extends `_${infer I }` ? I : K]: T[K]
};
type T4 = DropUnderscore<User> // "_id" and "_email" renamed to "id", "email"
Playground
id
in UpdatedUser to refer to the_id
in User. – yasersoPickRenameMulti
and some improvement withPickRenameMultiV2
in my updated answer, in case you are interested. – ford04