Merge pull request #33564 from backstage/fix/translation-ref-ts6-depth

fix(frontend-plugin-api): fix FlattenedMessages type depth for TypeScript 6
This commit is contained in:
Fredrik Adelöw
2026-03-25 08:57:43 +01:00
committed by GitHub
2 changed files with 15 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': patch
---
Fixed `FlattenedMessages` type to avoid excessive type instantiation depth in TypeScript 6 when using `createTranslationRef` with the `translations` option.
@@ -51,16 +51,16 @@ type FlattenedMessages<TMessages extends AnyNestedMessages> =
// 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,
_: TMessages[TKey] extends string
? { [_ in TKey]: TMessages[TKey] } // String values are leaf nodes, passed through with the same key
: TMessages[TKey] extends AnyNestedMessages
? FlattenedMessages<TMessages[TKey]> extends infer TNested // Recurse into nested messages, "local variable" for the result
? {
[TNestedKey in keyof TNested as `${TKey & string}.${TNestedKey &
string}`]: TNested[TNestedKey];
}
: never
: never, // Unreachable: TMessages[TKey] is always string or AnyNestedMessages
) => 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.