Skip to content

Constrain inferred types in return type positions of type guards #32894

@jscheiny

Description

@jscheiny

Search Terms

infer type guard generic conditional

Suggestion

When using the infer keyword in the predicate position of a type guard, the inferred type should be constrained by the type of the variable upon which it is predicated.

Use Cases

Recently ran into a case where we extended a simple type and wanted to extend an object of corresponding type guards to allow passing in this new type:

type MyType = "A" | "B" | "C";
type MyExtendedType = MyType | "D";

type ExtendGuards<T> = {
    [K in keyof T]:
        T[K] extends (value: MyType) => value is infer U
            ? (value: MyExtendedType) => value is U
            : T[K]
};

See in playground

Currently this produces an error both on infer U and on its usage on the following line:

A type predicate's type must be assignable to its parameter's type.
  Type 'U' is not assignable to type 'MyType'.
    Type 'U' is not assignable to type '"C"'.

It seems that it should only be possible to extend this type guard if U extends MyType, so it should probably just be constrained by that by default.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions