core-plugin-api: refactor and more comments for FlattenedMessages

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-11-24 15:57:13 +01:00
parent fb8f3bdbc2
commit 2f57070f79
@@ -42,21 +42,34 @@ type AnyNestedMessages = { [key in string]: AnyNestedMessages | string };
*
* @ignore
*/
type FlattenedMessages<T extends AnyNestedMessages> = {
[K in keyof T]: (
x: T[K] extends infer V
? V extends AnyNestedMessages
? FlattenedMessages<V> extends infer FV
? {
[P in keyof FV as `${K & string}.${P & string}`]: FV[P];
}
: never
: Pick<T, K>
: never,
) => void;
} extends Record<keyof T, (y: infer O) => void>
? { [K in keyof O]: O[K] }
: never;
type FlattenedMessages<TMessages extends AnyNestedMessages> =
// Flatten out object keys into a union structure of objects, e.g. { a: 'a', b: 'b' } -> { a: 'a' } | { b: 'b' }
// Any nested object will be flattened into the individual unions, e.g. { a: 'a', b: { x: 'x', y: 'y' } } -> { a: 'a' } | { 'b.x': 'x', 'b.y': 'y' }
// We create this structure by first nesting the desired union types into the original object, and
// then extract them by indexing with `keyof TMessages` to form the union.
// Throughout this the objects are wrapped up in a function parameter, which allows us to have the
// final step of flipping this unions around to an intersection by inferring the function parameter.
{
[TKey in keyof TMessages]: (
_: TMessages[TKey] extends infer TValue // "local variable" for the value
? TValue extends AnyNestedMessages
? FlattenedMessages<TValue> extends infer TNested // Recurse into nested messages, "local variable" for the result
? {
[TNestedKey in keyof TNested as `${TKey & string}.${TNestedKey &
string}`]: TNested[TNestedKey];
}
: never
: { [_ in TKey]: TValue } // Primitive object values are passed through with the same key
: never,
) => void;
// The `[keyof TMessages]` extracts the object values union from our flattened structure, still wrapped up in function parameters.
// The `extends (_: infer TIntersection) => void` flips the union to an intersection, at which point we have the correct type.
}[keyof TMessages] extends (_: infer TIntersection) => void
? // This object mapping just expands similar to the Expand<> utility type, providing nicer type hints
{
readonly [TExpandKey in keyof TIntersection]: TIntersection[TExpandKey];
}
: never;
/** @internal */
export interface InternalTranslationRef<