question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Infer type in conditional cannot unify generics

See original GitHub issue

TypeScript Version: 2.8.0-dev.20180315

Search Terms: infer conditional unify generic function

Code

type Apply1<T, V> = T extends (item: V) => infer R ? R : never;
type A1 = Apply1< (item: string) => string[] , string>;
type B1 = Apply1< <U>(item: U) => U[], string>;

type Apply2<T, V> = T extends (item: V, obj: infer R) => any ? R : never;
type A2 = Apply2< (item: string, obj: string[]) => any , string>;
type B2 = Apply2< <U>(item: U, obj: U[]) => any , string>;

type Apply3<T, V> = T extends (item: V, obj: infer R) => infer R ? R : never;
type A3 = Apply3< (item: string, obj: string[]) => string[] , string>;
type B3 = Apply3< <U>(item: U, obj: U[]) => U[] , string>;
{
	"compilerOptions": {
		"allowJs": true,
		"target": "es6",
		"module": "commonjs",
		"outDir": "dest",
		"strictNullChecks": true,
		"jsx": "preserve",
		"strictFunctionTypes": true
	}
}

Expected behavior: All A and B types are inferred to string[]. For types B, the type parameter U should be unified with string.

Actual behavior: All B types are inferred to {}[].

Related Issues: #22615 (different problem, but similar input)

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:15
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
fazouane-marouanecommented, Feb 4, 2019

Hi,

I’ll add a simple example related to this:

type GenericReturnType<T, TInput> = T extends (_: TInput) => infer TResult? TResult: never;

// Gives { x: {}; }
type Box = <T>(_: T)=> { value: T };
type _test1 = GenericReturnType<Box, number>;

// Gives {x: number; }
type AltBox<T> = (_: T)=> { value: T };
type _test2 = GenericReturnType<AltBox<number> | AltBox<string>, number>;
1reaction
ahejlsbergcommented, Mar 21, 2018

Repeating my comments from #22615 as they apply equally here:

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.

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

typescript: Infer generic requirement of type - Stack Overflow
The rule for when conditional types become distributive is that you are checking a "naked" or "bare" generic type parameter.
Read more >
Inferring types in a conditional type - Learn TypeScript
When item1 is constructed, the condition in the conditional type is true because number[] matches (infer E)[] . E is therefore inferred to...
Read more >
Lecture 8:Type Inference
The type inference problem is to take a program with no type annotations, ... It is easy to code up with heuristics for...
Read more >
Documentation - TypeScript 2.4
TypeScript 2.4 introduces a few wonderful changes around the way generics are inferred. Return types as inference targets. For one, TypeScript can now...
Read more >
typescript infer type - Sympa
Typescript cannot infer correct type from generic interface property. ... Conditional types in typescript allow you to introduce type variables into the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found