Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConfigService#get error 'Type instantiation is excessively deep and possibly infinite' when using any #906

Closed
2 of 4 tasks
micalevisk opened this issue Mar 27, 2022 · 2 comments · Fixed by #907
Closed
2 of 4 tasks
Labels
bug Something isn't working

Comments

@micalevisk
Copy link
Member

micalevisk commented Mar 27, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

this might be related with #625

When we supply some interface that has some prop with any to ConfigService generics, we got this tsc error:

TS2589: Type instantiation is excessively deep and possibly infinite

For instance:

// configuration.ts
export interface IConfig {
  foo: string
  // The following line introduces the TS error:
  bar: any
}
export default (): IConfig => ({
  foo: 'bar',
  bar: 123,
});
// app.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import type { IConfig} from './configuration';

@Injectable()
export class AppService {
  constructor(private readonly configService: ConfigService<IConfig, true>) {}
  getFoo(): string {
    return this.configService.get('foo', { infer: true });
  }
}

image

Minimum reproduction code

https://gitlab.com/micalevisk/nestjs-config-issue-906

Steps to reproduce

read the README of the repro above.

Expected behavior

build the code with no typing errors.

Package version

2.0.0

NestJS version

8.4.3

Node.js version

16.13.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

  • typescript version: 4.6.3 (the latest one)

I believe this is related with this type alias:

export type Path<T> = keyof T extends string
? PathImpl2<T> extends string | keyof T
? PathImpl2<T>
: keyof T
: never;

@micalevisk micalevisk added the bug Something isn't working label Mar 27, 2022
@micalevisk
Copy link
Member Author

This is due to this behavior of TS:

interface Good {
  foo: string
  bar: number
}

type A = Good[keyof Good]
//   ^? type A = string | number

interface Bad {
  foo: string
  bar: any
}

type B = Bad[keyof Bad]
//   ^? type B = any

and any is basically what's the T[Key] ends up being below:

export type PathImpl<T, Key extends keyof T> = Key extends string
? T[Key] extends Record<string, any>
?
| `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof any[]>> &
string}`
| `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}`
: never
: never;

which makes that T[Key] extends Record<string, any> always true

@kamilmysliwiec
Copy link
Member

Let's track this here #907

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants