Skip to content

Track constraints for index operator (and possibly other type operators) #25804

@bterlson

Description

@bterlson

Today if you use a conditional type whose LHS is something other than a simple type parameter, the constraint is not tracked on the RHS, making some simple patterns more complex than they need to be:

type ReturnTypeOfMethodIfExists<
  T,
  S extends string
> = S extends keyof T
  ? T[S] extends (...args: any[]) => any ? ReturnType<T[S]> : void // Error: T[S] doesn't satisfy constraint (... args: any[]) => any
  : void;

interface I {
  on: () => number
}

type t1 = ReturnTypeOfMethodIfExists<I, 'asdf'>;
type t2 = ReturnTypeOfMethodIfExists<I, 'on'>;

// despite the type error above, t1 and t2 do check properly (t1 is void, t2 is number).

In order to make this work, you need to introduce a wrapper like so:

type ReturnTypeOfMethod<T> = T extends (...args: any[]) => any
  ? ReturnType<T>
  : void;
type ReturnTypeOfMethodIfExists<T, S extends string> = S extends keyof T
  ? ReturnTypeOfMethod<T[S]>
  : void;

It would be nice if we could track constraints on at least index access as conditionals on properties of object types seem quite common and useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions