type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type G = Getters<{ name: string; age: number }>;
{ getName: () => string; getAge: () => number }The answer is { getName: () => string; getAge: () => number }. The as clause renames each key with a template literal type. Capitalize makes the first letter uppercase, so name becomes getName. The value is a function that returns the original property type.{ getname: ... } is wrong because it ignores Capitalize. { getName: string; ... } is wrong because it ignores the () => function type.
Why string & K? keyof T can include string, number and symbol keys. Capitalize only accepts strings. The intersection string & K keeps only the string keys, and number and symbol keys become never, so they are dropped.
Read more