I'm trying to come up with a typescript type that takes an object and sets all keys of type number
to be string
. The following doesn't work:
export type ChangeTypeOfKeys<T extends object> = {
[key in keyof T]: key extends number ? string : T[key]
}
const c: ChangeTypeOfKeys<{ a: number, b: boolean }> = {
a: 'ok',
b: false,
}
The resulting type should be { a: string, b: boolean }
, but instead I get a TS error:
Type 'string' is not assignable to type 'number'.(2322)
input.tsx(5, 29): The expected type comes from property 'a' which is declared here on type 'ChangeTypeOfKeys<{ a: number; b: boolean; }>'
I think the issue is related to how I'm using key
in key in keyof T
, since replacing key extends number
with another argument works:
export type ChangeTypeOfKeys<T extends object, Replace> = {
[key in keyof T]: Replace extends number ? string : T[key]
}
const c: ChangeTypeOfKeys<{ a: number, b: boolean }, number> = {
a: 'ok',
b: 'ok',
}
Not sure if there are any special properties with key
that I'm missing here. TIA!
CodePudding user response:
To get the value of property referenced by key
, do this:
export type ChangeTypeOfKeys<T extends object> = {
[key in keyof T]: T[key] extends number ? string : T[key]
// ^^^^^^
}
The type of key
will always be string
in the example you gave. To be absolutely clear, in your code:
key
refers to the name of a property,T[key]
refers to the property namedkey
on typeT
.
Also note, extends object
allows for []
types (among others), which might not be what you want. Try extending from {}
or Record<string, any>
instead.