Repository: TypeScript
Issue: Type Instantiation is Excessively Deep Regression In #56004
Labels: Needs Investigation

### 🔎 Search Terms

Type Instantiation is Excessively Deep, #56004

### 🕗 Version & Regression Information

This changed in commit 38ef79e0b02ad122b984a19f3494414e4e53c896

### ⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAQg9gExAYQBYQMYGsDOAJCAJwEtgBDAcwgB4B5APigF4paoIAPYCAOwRygAFADZkMEMgCNhEWpIBWmYFAD8rKAC4oPCADciAbgBQoSFGRweOYITLEewNJlwES5KnXZde-IaPFSMnKKGMCMLGQ8IMZGAPSxUAByZAC20CkArtZe3HxQOHBpwKj2FFDEAHQQFVAABgDiEI6WAGbEFBmEEAjUyWnhUBVDtVAYhWDEMgKSGcrFxAIIcBA4PADkwBUm4NCNzTxtHV09fdCcub6RIAMWVjZ2Dk7Y+ESklDRGULCIKOjPrm8PJ8vlB4uZUJEKKUoPMBMA4HVTjkfAIAEQAQRSkmIvGAABl2qhgKjVFBMdjcQSKETNFAACpwLC8EZtDgrGHoUbjSZkYDESxbEFQACSd0i4jpO2owKFSPOKKgGKxOIcVKJJLUpggcBaZOVlMJyi0Wp19MZvBlUHowOt9BiYPRMJ2UDAZFsRSI5QEXQAjhliMcoC04IQOQsuSkJqI+ZYg3ZhJ1qiLlBhIlBJNAst0oJEEPk+cJhHHJjCEWNI5NoDNlMRdaQ1t6ICk4Po87iAxBhCByinuVMtghMKIuqNRDgBCIxBJpLIFEpqABVHhZvMRKKMADewLBDOLRfhEaj6SyvYcDxzPCgcDAMZ4ZCLYEI16IoA5vKgXRaRDhCNqsNqgo5ioxolDgMRfDuoEuk+kCEK+nALMAP5QAgtZfl0DjELy0AtE+KQctAWp1BuAC+IzVj2XrrMoYjABk95dtomArDgbrdgeqZZgRh48ree6JoBADEPBwMAACikagMahAZBAxgkUYcQJLuOCoHAADuYYCOWUa8vyl4tPGibcRgY7aXAGTCHmwikEQDHdhmUDyCedSmWQ456hSqqGlApEAcmUAQshCHZMUFnUgOQ5utAbkeeSKr4j58p8BO-jTkEc6hL5wLCaJEk3iA0myfJimDm5I6xQIDJMpeyW+JOAQzsESjZRBCQALIuZ+noHpEonoKGj7PnBIA1H+oEjPeljQAs1HsCJGQRcCkggQsADaqIYKiAC64GggktA8IxIVIaW6bQN1hCBvCNR0pgqA8MQqaFt2IAWVyll5l0zb6FpF55sU0Copw4jjsQ+iMYOEBgCSRBPqGSwrHNFAImQ6lkKN24JHgGl6D1EIpmQWYCH1gOhjpvH6ewV0hoBGBaMuWKGEYJFAA

### 💻 Code

```ts
type BodyChecksHeritage<O> = O extends PlaceableObject ? O : never;
type ConstraintChecksHeritage<O extends PlaceableObject> = any;

// Name must extend something i.e. `GetConfigured<Name> = ...` compiles but this doesn't.
type GetConfigured<Name extends any> = ConstraintChecksHeritage<
  BodyChecksHeritage<
    // Changing this to `Name extends "AmbientLight" ? AmbientLight : Token` fixes the compilation.
    InstanceType<
      Name extends "AmbientLight" ? typeof AmbientLight : typeof Token
    >
  >
>;

// A type parameter is required for this compilation failure. It can be used and still fail to compile but if it's removed entirely it compiles.
declare class PlaceableObject<Unused = any> {
  // To fail to compile must contain an optional property that refers to `this`.
  a?: this;

  // This property exists to differentiate from the type `{}` but it isn't actually necessary to cause the compilation failure.
  #notEmpty: true;
}

// To show this compilation failure the class could literally be just `class AmbientLight {}`. It has to exist though.
declare class AmbientLight extends PlaceableObject {
  #notEmpty: true;
}

declare class Token extends PlaceableObject {
  // Must refer to another property. `this` alone isn't enough.
  b: this["c"];

  // Only exists to be referred to. Technically you could remove this and the "excessively deep" error doesn't go away.
  // However that causes another compilation error.
  c: number;
}
```


### 🙁 Actual behavior

Gets the error "Type instantiation is excessively deep and possibly infinite."

### 🙂 Expected behavior

No error.

### Additional information about the issue

I've seen somewhat similar issues reported about this PR but none of them seemed to match my issue. However some were closed without reproduction and maybe I'm having the same problem as [type-fest is?](https://github.com/microsoft/TypeScript/pull/56004#issuecomment-1914382123)

I've reduced the code down from a large project into this which is why it seems utterly contrived. A few of the odd requirements seem to be explainable:
- `Name extends any` is required because #56004 only operates in cases where the type parameter is constrained.
- `BodyChecksHeritage` and `ConstraintChecksHeritage` are both required to increase the depth.

But that leaves some things I can't personally explain such as:
- Why is `a?: this` causing issues but `a: this | undefined` or others don't necessarily?
- Why does `PlaceableObject` have to be generic?
- etc.

I've noted more oddities inline with the code.