I'm needing to update the value of a property of a class by a string property name. I started off by making sure the property name was valid via this method:
export class ClientDTO {
...
static isValidPropertyName(name: string): name is keyof ClientDTO {
return (name as keyof ClientDTO) !== undefined
}
}
And then in another class I'm doing this:
foo(key: string, newValue: string) {
if (!ClientDTO.isValidPropertyName(key)) {
return
}
if (newValue !== this.originalClient[key]) {
// @ts-ignore
this.originalClient[key] = newValue
}
}
The lookup works well now, but to do the update I'm having to put the // @ts-ignore
there and I'd really like to figure out how to do this properly without having to have the ignore there.
I have strict checkings turned on so I get the error
TS2322: Type 'any' is not assignable to type 'never'
This doesn't check that
name
is a key of ClientDTO. It asserts that it is, and then checks whether the string is undefined. Try it in the playground.Even if that worked, it would only check that the string is a valid key of ClientDTO, but does not say which one it is. Therefore, Typescript checks that the type you're setting is safely assignable to any key of ClientDTO; since ClientDTO contains "a mix of types" including "String, Boolean, date and number", the only safe value to assign is
never
.For you to safely assign a
newValue: string
, you'll need a function that ensures at runtime that yourkey
is for astring
-typed property, which might involve some duplication.typescript playground
See also: Typescript error:Type 'number' is not assignable to type 'never'