'Rename key of typescript object type
I have this:
type Two = {
one: number,
two: string,
three: boolean
}
I want it to create a type that would look like this:
type RenamedTwo = {
one: number,
two: string,
four: boolean // difference
}
Tried to create it this way:
type Rename<T, K extends keyof T, N> = Pick<T, Exclude<keyof T, K>> & { [N]: T[K] }
In an attempt to use this way:
type Renamed = Rename<Two, 'three', 'four'>
But TSlint marks [N]
as error and gives this error message:
[ts] A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type. [ts] 'N' only refers to a type, but is being used as a value here.
Solution 1:[1]
You need to use a mapped type for the renamed property as well:
type Two = {
one: number,
two: string,
three: boolean
}
type Rename<T, K extends keyof T, N extends string> = Pick<T, Exclude<keyof T, K>> & { [P in N]: T[K] }
type Renamed = Rename<Two, 'three', 'four'>
Note that this will not work as expected if you provide more properties:
type Renamed = Rename<Two, 'two' |'three' , 'four' | 'five'> // will be Pick<Two, "one"> & {
// four: string | boolean;
// five: string | boolean;
// }
Solution 2:[2]
In the current typescript version 4.6.2, there is a remapping gramma to use. It can be implement this much easier.
type RenameByT<T, U> = {
[K in keyof U as K extends keyof T
? T[K] extends string
? T[K]
: never
: K]: K extends keyof U ? U[K] : never;
};
type Two = { one: number; two: string; three: boolean };
// retrunType = { one: number; two: string, four: boolean };
type renameOne = RemaneByT<{three: 'four', five: 'nouse'}, Two>;
// returnType = { x: number, y: string, z: boolean; }
type renameAll = RenameByT<{one: 'x', two: 'y', three: 'z'}, Two>;
The RenameByT
type can separate by several parts.
The explain is for the example renameOne
K in keyof U
means all the key inU
. For the example isone | two | three
as
clause since ts4.1 can use. but i can't use in 4.4.4 but can use in 4.6.2. This is use to rename KeyK
by the condiction typeK extends keyof T
. keyof T meansthree | five
.T[K] extends string
meansT[K]
is string.T['three']
is string so returnsfour
,T['five']
returnsnouse
;- the return type
K extends keyof U
, soT['three']
is satisfy so return{ four: U['three'] }
means{ four: boolean}
- ohters keys return as origin
reference:
https://github.com/microsoft/TypeScript/issues/40833 https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Titian Cernicova-Dragomir |
Solution 2 |