I am using TypeScript 4.9.5
and I need to utilize type remapping. During the remapping process, I want to maintain the optional property mode
. Specifically, I need to add a "child" prefix
to each property of an interface and convert the original literal types of properties to uppercase. Here is my interface definition:
interface ChildrenProps {
children: ReactNode;
className?: string;
style?: CSSProperties;
}
I expect to transform it into the following form:
interface ChildrenPropsWithPrefix {
childChildren: ReactNode;
childClassName?: string;
childStyle?: CSSProperties;
}
To achieve this, I have written the following type utility:
/** Make all properties with a prefix and convert the first character of properties to uppercase */
type PrefixAll<T, P extends string> = {
[K in keyof T & string as `${P}${Capitalize<K>}`]: T[K];
}
However, the result I obtained is as follows:
interface ChildrenPropsWithPrefix {
childChildren: ReactNode;
childClassName: string;
childStyle: CSSProperties;
}
As you may notice, there is a difference between this result and my expected outcome. All the properties have become required
, TS Playground link, whereas I want them to remain optional
.
Although I can address this issue by making ParentProps extend Partial\<PrefixAll\<ChildrenProps, 'child'\>\>
, it alters the original structure of the interface, which might confuse other developer. I would like to avoid such a situation.
Can you suggest a solution or alternative approach that allows me to achieve the desired result while maintaining the optional property mode? I would greatly appreciate any code examples or insights you can provide.