Suppose I have some interfaces in TypeScript:
export interface IStateA {
id: number;
}
export interface IStateB {
text: string;
moreText: string;
}
Is there a way to generate the following interfaces without having to manually do so?
export interface IStateASetters {
setId: (number) => void;
}
export interface IStateBSetters {
setText: (string) => void;
setMoreText: (string) => void;
}
Note the following:
- the new interface name is the same as the old one, except with
Setters
appended - the new interface has methods that take in the type of the corresponding property of the old interface
- the new interface method names are the same as the old property names, except with
set
prepended and the first letter of the old name capitalized.
Totally understandable if this isn't possible, partial answers are very welcome!
CodePudding user response:
If you combine a mapped type with string literals and key renaming, you can do this.
With something like:
type WithSetters<T> = {
[K in keyof T & string as `set${Capitalize<K>}`]:
(newValue: T[K]) => void
}
The one tricky part here is the & string
. That's necessary because because a type may have non string keys (numbers, or symbols). But this transformation only makes sense for string keys. So by intersecting the keys with string
you can be sure to only map the string
keys.