#Typescript 5.2.2 makes code not compile, see below

20 messages · Page 1 of 1 (latest)

terse glacierBOT
#
onkeltem#0

Preview:```ts
class Api {
foo = {
method1: (param: string) => "",
method2: (param: string) => "",
}
}

type ApiSections = Pick<Api, "foo">

type FirstParam<
T extends keyof ApiSections,
K extends keyof ApiSections[T]

= Parameters<ApiSections[T][K]>```

silent gust
#

It works on 5.1.6.
I cannot grasp what has changed...

#

The Parameters utility wasn't changed with 5.1.6 > 5.2.2 transition:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never
silent gust
#

That's really strange

#

So the error is:

Type 'ApiSections[T][K]' does not satisfy the constraint '(...args: any) => any'.
  Type 'ApiSections[T][keyof ApiSections[T]]' is not assignable to type '(...args: any) => any'.
    Type 'ApiSections[T][string] | ApiSections[T][number] | ApiSections[T][symbol]' is not assignable to type '(...args: any) => any'.
      Type 'ApiSections[T][string]' is not assignable to type '(...args: any) => any'.
        Type 'Api[T][string]' is not assignable to type '(...args: any) => any'.
#

Why it was expanded this way?:

ApiSections[T][string] | ApiSections[T][number] | ApiSections[T][symbol]
#

keyof ApiSections[T] should be:

"method1" | "method2"
#

An extended version:

terse glacierBOT
#
class Api {
  foo = {
    fooMethod1: (param: string) => '',
    fooMethod2: (param: number) => '',
  };
  bar = {
    barMethod1: (param: boolean) => '',
    barMethod2: (param: object) => '',
  };
}

type ApiSections = Pick<Api, 'foo' | 'bar'>;

type MethodParams<T extends keyof ApiSections, K extends keyof ApiSections[T]> = Parameters<ApiSections[T][K]>;
//                                                                                          ^^^^^^^^^^^^^^^^^
// Type 'ApiSections[T][K]' does not satisfy the constraint '(...args: any) => any'.
//   Type 'ApiSections[T][keyof ApiSections[T]]' is not assignable to type '(...args: any) => any'.
//     Type 'ApiSections[T][string] | ApiSections[T][number] | ApiSections[T][symbol]' is not assignable to type '(...args: any) => any'.
//       Type 'ApiSections[T][string]' is not assignable to type '(...args: any) => any'.
//         Type 'Api[T][string]' is not assignable to type '(...args: any) => any'.

type FooMethod1Params = MethodParams<'foo', 'fooMethod1'>;
//   ^? - type FooMethod1Params = [param: string]
type FooMethod2Params = MethodParams<'foo', 'fooMethod2'>;
//   ^? - type FooMethod2Params = [param: number]
type BarMethod1Params = MethodParams<'bar', 'barMethod1'>;
//   ^? - type BarMethod1Params = [param: boolean]
type BarMethod2Params = MethodParams<'bar', 'barMethod2'>;
//   ^? - type BarMethod2Params = [param: object]
silent gust
#

Another odd thing: despite the error message, the type utility MethodParams continues to function properly 😕

lunar pendant
#

here's a reduced example, in case it's helpful:

terse glacierBOT
#
mkantor#0

Preview:```ts
type Api = {
foo: {
f: () => void
}
bar: {
g: () => void
}
}

type MethodParams<T extends keyof Api> = Parameters<
Api[T][keyof Api[T]]

lunar pendant
#

i tried a few of the PR builds. no smoking gun yet, but 5.2.0-pr-55267-8, 5.2.0-pr-55222-9, and 5.2.0-pr-55214-6 all demonstrate the problem, while 5.2.0-pr-55177-9 and 5.2.0-pr-55224-37 do not

soft trout
#

It fails on 5.0.4 as well

lunar pendant
#

interesting, yeah and the 4.x versions i tested too now that you mention it. maybe this was a regression in 5.1 that was fixed? or something that was improved in 5.1 that regressed again in 5.2?

#

i'm trying to rationalize why it'd error to begin with, maybe something to do with excess properties

soft trout
#

This also seems to work:

type Root<T extends keyof Api> = Api[T][keyof Api[T]]
type Bar = Root<'bar'>

type MethodParams<T extends keyof Api> = Parameters<Bar>

Obviously T is unused in the last line

broken sundial
silent gust
#

That's a huge chunk of work you've done folks! Thanks. @lunar pendant @soft trout @broken sundial