My current mapping type has been effective in many scenarios:
type WithKeyPrefix<P extends string, T extends {}> = {
[K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
};
However, I'm facing an issue with rejecting objects that have non-string keys. I've experimented with different approaches but haven't found one that meets my requirements:
type WithKeyPrefix<P extends string, T extends {}> = {
[K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
} & {
[K in Exclude<keyof T, string>]: never;
};
type WithKeyPrefix<P extends string, T extends Record<string, unknown>> = {
[K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
};
The first modification doesn't seem to have any effect. The second modification throws this error when T
is an interface with limited keys:
TS2344: Type 'Foo' does not satisfy the constraint 'Record<string, unknown>'.
Index signature is missing in type 'Foo'.
Is there a way to define the type of T
as desired?
Extra question: Why do we need Extract<keyof T, string>
even when T
is restricted to Record<string, unknown>
?
I've reviewed this question before, but the solutions provided are effective workarounds in that context, not applicable to my scenario. Hence, the need for this new question.