Skip to content

Conditional types do not work in generic functions #53455

Closed
@ns-vpanfilov

Description

@ns-vpanfilov

Bug Report

I've created a type that converts all undefined properties to optional. This types works well, however fails when used in generic functions:

type UndefinedKeys<T> = { [P in keyof T]: undefined extends T[P] ? P : never }[keyof T]
type OptionalUndefined<T> = Partial<Pick<T, UndefinedKeys<T>>> & Omit<T, UndefinedKeys<T>>

🔎 Search Terms

generic function

🕗 Version & Regression Information

This is the behavior in every version I tried ( 5.0.2 and 4.9.5 )

⏯ Playground Link

Playground link with relevant code

💻 Code

type UndefinedKeys<T> = { [P in keyof T]: undefined extends T[P] ? P : never }[keyof T]
type OptionalUndefined<T> = Partial<Pick<T, UndefinedKeys<T>>> & Omit<T, UndefinedKeys<T>>

type TSample<
  U extends Record<string, any> | undefined,
  D extends Record<string, any>
> = { undef: U, def: D }


function fn<
  U extends Record<string, any> | undefined,
  D extends Record<string, any>
>(params: OptionalUndefined<TSample<U, D>>) {
  {
    // ERROR: both properties do not exist on type 'OptionalUndefined<TSample<U, D>>'
    const { def, undef } = params
  }

  {
  // works as expected
  const { def, undef } = params as OptionalUndefined<
      TSample<
        Record<string, any> | undefined,
        Record<string, any>
      >
    > 
  }
}

🙁 Actual behavior

typescript cannot properly determine parameter type

🙂 Expected behavior

I expect typescript to use definition of U (extends Record<string, any> | undefined) and D (``) to be used to determine the type of parameters and params should have `{ undef?: Record<string, any> | undefined, def: Record<string, any> }` type?

Notice how, when I explicitly specify the type of params, it works properly.

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