-
Notifications
You must be signed in to change notification settings - Fork 13k
Regression: Mapped type with recursive key remapping crashes tsc with "RangeError: Maximum call stack size exceeded" in [email protected]+Β #60476
Description
π Search Terms
"Mapped type", "Recursive mapped type", "Recursive type", "RangeError: maximum call stack size exceeded"
π Version & Regression Information
- This changed between versions 5.3.3 and 5.4.5
β― Playground Link
π» Code
export type FlattenType<Source extends object, Target> = {
[Key in keyof Source as Key extends string
? Source[Key] extends object
? `${Key}.${keyof FlattenType<Source[Key], Target> & string}`
: Key
: never]-?: Target;
};
type FieldSelect = {
table: string;
field: string;
}
type Address = {
postCode: string;
description: string;
address: string;
}
type User = {
id: number;
name: string;
address: Address;
}
type FlattenedUser = FlattenType<User, FieldSelect>;
// ^?
π Actual behavior
Compilation crashes with "RangeError: maximum call stack size exceeded"
π Expected behavior
No crash with the type working correctly or explicit error on the recursive type like "Type instantiation is excessively deep and possibly infinite. ts(2589)"
Additional information about the issue
Same playground in version 5.3.3 where the type resolves with no crash
https://www.typescriptlang.org/play/?ts=5.3.3#code/KYDwDg9gTgLgBDAnmYcBiAbAhjGwB2AKssADwDKEArlAMaqh74AmAznBAEYBWwtMAGjiEsUAObAYAPjgBeOAG8AUHDgBtANLBEcAJb44Aa20QAZnEo16cLOy07GBNnFYwo+sStVwA-Bep0wJraALpwjizsXLz8Xt6+cAAGACQK9gC+AHSpxohm6Ni4BMQoFAH0wYghQiLikjIAZC5uHumJcd4AXHD2Hd34wABuwFAhALQ+3bUSMADcSunzSkgo6LrAGMzkG3zw8sqqMFicGMDdru74YvOqpuub5y1X8+lKyyRwAILMzFDArOx9l5IK4AMIQZhnZqXa5eSGsWjuMAwXQQfCPGE3Gw-P4AjEeF5vFaoACqrBGckUXl0zH6VAAtpwRlj8Fh6VCLgSvFgcf9WN1vr8+YT3qtMDgmMBmGSKfJxUUiCRSDKoEI0Pctjt+FJ5gB6XXxQ0APR8QA
We ran into this crash when upgrading the ts version in our project.
There's a workaround based on the approach described in https://blog.swmansion.com/deep-flatten-typescript-type-c0d123028d82 which doesn't cause a crash on these versions.
The original type that caused the crash has mostly the same motivation as the blog post above. The provided snippet was simplified to a minimal reproducible example.