Skip to content

Value accessed with generic that extends keyof does not compile when passed to conditional typeΒ #62668

@undeadcat

Description

@undeadcat

πŸ”Ž Search Terms

keyof, conditional type, generic

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.3#code/KYDwDg9gTgLgBASwHY2FAZgQwMbDgZTQDcFcBhKYAE2BQUwBsBnOAbwCg44BtAIgHMIEfg2C8AugC426IZKYwoyfgF8A3JzgB6LXAC20PGCgQSNKCwAWaYABo4igK5JsmVFTiyocAEaUSMACe7Crs7KCQsA6BYHgAUvgA8gByZBB6YG4IPqIAPAAqAHxwALxwYVzc+eJwoKhIVCzcACJuwOKaOtDlXFw6cPm1IPWNcK2omgD8cEjARGidugaUcAzCpHDWlPZOLm0eXr7+CEGa0vlhEdDwNNgMmCvoztgwCBBIDhBxTO8FhQAUREY0gSKTSGSyOWAfwAlNIiBAEFQNGEni5Xu9NpgGqJCKIXtQKNRaK9GAUhiMWABrYCBCDoAjEUjAIk0OiMJgA7CUKj5GLAc72bnUaSEKAkcg8kn0ZgwtiabDvBQOSwIJis6XAxni5ka9nMKo1MrCqjcE182LiFFcGBfH5IXJiiUsqX6piGgEwVXq12khgwlGhdj9ZAjahwRxMTD8PD0uCg1LpTKvKEzCDwW1wRUZBCiTY2YO6RVIZUgSTjPBlWYAdzGbX+MMLn2+73+IEbTYgVKbtpbDqdut9MvdAiEIjE4k93r1foD7CAA

πŸ’» Code

export interface ServiceCredentials {
  ["google"]: {foo:string};
  // more providers here, truncated for brevity
}

export type JSONCompatible<T> = 

  [T] extends [Date]
  //or 
    // T extends Date
  ? never
  // more logic here, truncated for brevity
  : T

export declare function toJson<T>(val: JSONCompatible<T>): void;


function handleSelectedCredential<T extends keyof ServiceCredentials>(credType: T, cred: ServiceCredentials) {
  const thisCredential: ServiceCredentials[T] = cred[credType];

  toJson<ServiceCredentials[T]>(thisCredential);
}

πŸ™ Actual behavior

Argument of type 'ServiceCredentials[T]' is not assignable to parameter of type 'JSONCompatible<ServiceCredentials[T]>'.
  Type '{ foo: string; }' is not assignable to type 'JSONCompatible<ServiceCredentials[T]>'.(2345)

πŸ™‚ Expected behavior

I would expect the file to compile.
This similar code that does not use a generic compiles:

declare const x: keyof ServiceCredentials

function handleSelectedCredential(cred: ServiceCredentials) {
  const thisCredential: ServiceCredentials[typeof x] = cred[x];

  toJson<ServiceCredentials[typeof x]>(thisCredential);
}

Additional information about the issue

Note that I have tried both versions of JSONCompatible, taking into account distributive conditional types:

export type JSONCompatible<T> = [T] extends [Date] ? never : T
export type JSONCompatible<T> = T extends Date ? never : T

The result is the same for me.

The intended behavior of the original version of JSONCompatibleΒ is to prohibit values that don't deserialize to the same value (e.g. JSON.parse(JSON.stringify(new Date())), originally it contained more code. This is the minimal example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions