Repository: TypeScript
Issue: Possible performance improvement around types with `this` argument
Labels: Help Wanted,Possible Improvement

# Bug Report

I've found a hotspot in a [`graphql-code-generator`](https://github.com/dotansimha/graphql-code-generator/) project where a comparison of types was taking a significant amount of time:

<img width="1209" alt="CleanShot 2023-05-16 at 11 15 26@2x" src="https://github.com/microsoft/TypeScript/assets/9019397/0cae33a6-ae6b-4401-8962-8ea7b27481c1">

It comes from a [`packages/presets/client/src/babel.ts` file](https://github.com/dotansimha/graphql-code-generator/blob/86ec182887698742af8e9f47ffe39f07772e54a4/packages/presets/client/src/babel.ts#L16),  and it's related to the usage of a `declare` function. Specifically, the comparison between `PluginObj` types was costly.

The `declare` function from Babel, has the following signature:

```ts
export function declare<
    O extends Record<string, any>,
    R extends babel.PluginObj = babel.PluginObj
>(
    builder: (api: BabelAPI, options: O, dirname: string) => R,
): (api: object, options: O | null | undefined, dirname: string) => R;
``` 

I added the first generic parameter to the usage of `declare`, and it successfully eliminated the hotspot:

```ts
type ClientBabelPresetOptions = {
  artifactDirectory?: string;
  gqlTagName?: string;
};
export default declare<ClientBabelPresetOptions>((api, opts): PluginObj => {
// ...
```

Trace after that change:
<img width="846" alt="CleanShot 2023-05-16 at 11 09 40@2x" src="https://github.com/microsoft/TypeScript/assets/9019397/791fdd22-ef64-4253-9a16-40a9307f1ddd">


I understand that by doing this, TS could use a default for the second parameter, `R`, and hence skip the inference.

**But here comes an interesting find** — when I provided **both** generic parameters, it went back to the same (slow) performance result as in the beginning:

```ts
export default declare<ClientBabelPresetOptions, PluginObj>((api, opts): PluginObj => {
```

Note: using `PluginObj` vs `PluginObj<PluginPass>` or even `PluginObj<any>` yields the same problem.

I paired with @Andarist, and he found out that even though the types looked the same, the **target type** (`PluginObj`) had an extra `this` argument. That led to `getVariancesWorker` being called on rather expensive types.

**Now, the question is:** why in `checkTypeArguments` the `fillMissingTypeArguments` doesn't use the `this` type anyhow but the constraint's type is obtained with the `this` type: 
```ts
getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument)
```

If they would share the same ID then this particular case could work much faster. 


### 🔎 Search Terms

performance, this, babel, getTypeWithThisArgument

### 🕗 Version & Regression Information

- TypeScript version: 5.0.4

### ⏯ Playground Link

[Playground link with relevant code](https://tsplay.dev/N73R4N)

### 💻 Code

The code could be found here: https://github.com/dotansimha/graphql-code-generator/blob/86ec182887698742af8e9f47ffe39f07772e54a4/packages/presets/client/src/babel.ts#L16.

Currently, this file has an "improved" version, but upon playing with it you can notice long check times when:
1. You remove `ClientBabelPresetOptions` 
2. You add a second generic parameter, `PluginObj`

To reproduce this in `graphql-code-generator`:

1. Clone
2. Install deps: `yarn`
3. Run TSC

### 🙁 Actual behavior

Comparing two similar types takes a long time.

### 🙂 Expected behavior

Skip `getVariancesWorker` being called in this case.