Skip to content

Excessive depth exploring template literal type constraints #40970

@ahejlsberg

Description

@ahejlsberg

TypeScript Version: 4.1.0-dev

Code

type PathKeys<T> =
    T extends readonly any[] ? Extract<keyof T, `${number}`> | SubKeys<T, Extract<keyof T, `${number}`>> :
    T extends object ? Extract<keyof T, string> | SubKeys<T, Extract<keyof T, string>> :
    never;

type SubKeys<T, K extends string> = K extends keyof T ? `${K}.${PathKeys<T[K]>}` : never;

type PropType<T, Path extends string> =
    Path extends keyof T ? T[Path] :
    Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
    unknown;

declare function getProp<T, P extends PathKeys<T>>(obj: T, path: P): PropType<T, P>;

const obj = {
    name: 'John',
    age: 42,
    cars: [
        { make: 'Ford', age: 10 },
        { make: 'Trabant', age: 35 }
    ]
} as const;

let make = getProp(obj, 'cars.1.make');  // 'Trabant'

Expected behavior:

No errors.

Actual behavior:

"Type instantiation is excessively deep and possibly infinite" error on declaration of getProp.

Playground Link:

https://www.typescriptlang.org/play?ts=4.1.0-dev.20201006#code/C4TwDgpgBACghsAFgaQiAzgHgCoD4oC8AUFKVNlBAB7AQB2AJulAE4RwMD2dANiFHDogA2gF0oAfigBRGizgBjYJgDWaTgDNyAGigADACQBvOgFcAtgCMILAL578AHygBlU5dQYcu2cHlLVdS1sXUMTC2s7B3wALhIyCmpaRmZOSwArCCVJGTlFZTUQTR0odD8ASzoAcydXd08sENy-fMCi4N0ylkqa2PjSOggANxsAbiIiUEg6jzRG3WRKGnomUorq-AIoRaSV5kLiiikw5FsAOmN4JAacYWRRXHsoGKhBkZZxyfBoGBZOMGw328sAQiCWyVWXR6m36IKQ4L2UAOwRy2GEV0Q4jiZDhYN2KX0xkqGhs23ORLoJJYUAASk8pDtlgTkeQcr9-oDILd7roabEoKY6Co6JwAO50Z6wwXCsV0T4MLI8OBsKAaQVKcrcKBVCDAdlgYEwBEEjE3PC4AAUaXSLyaYFBLxgAEpHX8AUCmjBcJ8FNwylBrYQoEZYXQ4OYIC8AOQAKU4iDoUe0sLgOpeABYAEzJnEKZXoF7CWE4oxQcxwNTRgBinBYDCTAjTUAAjAAGKC2HM4sil8uVqBR7DySyCYAN1ORqAAZgArB3YaIiLYBMxfXQyp8eLqyxXoFsdXq3VaMroo3mWOgzs2zn2IFGnaNSAB6J8DodwEd0MdEIA

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions