Skip to content

Adding infer in a conditional type changes the resulting branch #22615

Description

TypeScript Version: 2.8.0-dev.20180315

Search Terms:
infer conditional generic function

Code

type Id = <T>(item: T) => T;

type X = ((t: Id) => void) extends (t: (item: any) => any) => void ? "yes" : "no";
// Resolves to "yes", as expected

type Y = ((t: Id) => void) extends (t: (item: any) => infer R) => void ? "yes" : "no";
// Resolves to "no", but "yes" is desired

The code checks whether a function that takes the identity function is assignable to a function that takes some function any => any. This is clearly assignable, and thus results in "yes". However, when replacing one any by infer R, the other branch is taken. I think that replacing any by an infer R type should never change the branch that is taken.

{
	"compilerOptions": {
		"allowJs": true,
		"target": "es6",
		"module": "commonjs",
		"outDir": "dest",
		"strictNullChecks": true,
		"jsx": "preserve",
		"strictFunctionTypes": true
	}
}

Expected behavior:
X and Y resolve to "yes"

Actual behavior:
Y resolves to "no"

Related Issues:

Activity

  1. RyanCavanaugh commented on Mar 16, 2018

    @RyanCavanaugh
    Member
  2. ahejlsberg commented on Mar 21, 2018

    @ahejlsberg
    Member

    It is effectively a design limitation. We have the concept of instantiating a generic function type in the context of a non-generic function type (a form of unification), but we currently don't do that in conditional types. Instead, function type parameters are erased to their constraints and we infer from those. In the example above, that causes us to infer {} for the infer R type parameter. Ordinarily that would be fine because anything is assignable to {}, however in this case the type parameter occurs in a contra-variant position, so the check fails following inference. This isn't specific to conditional types, a similar thing can happen during regular type inference in function calls.

    The proper fix for this would be have type inference perform instantiation of a source type in the context of a target type when the source type is a generic function type.

  3. added
    Design LimitationConstraints of the existing architecture prevent this from being fixed
    and removed
    BugA bug in TypeScript
    on Mar 21, 2018
  4. locked and limited conversation to collaborators on Jul 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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