Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generics and type inference #15095

Closed
Roam-Cooper opened this issue Apr 10, 2017 · 3 comments
Closed

Generics and type inference #15095

Roam-Cooper opened this issue Apr 10, 2017 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@Roam-Cooper
Copy link

Roam-Cooper commented Apr 10, 2017

TypeScript Version: 2.2.2 / nightly (2.2.0-dev.201xxxxx)

Code

export class Thing<T>{
    constructor(input: Fruit<T>, mapping: () => T) { }
}

new Thing(Fruit<apple>null, ()=>{
return {};
});

Expected behavior:
Compiler complains that {} is not assignable to Fruit as the compiler sees T as a Fruit<apple> FIRST.
Actual behavior:
Compiler finds best common type between Fruit<apple> and {} for T which ends up being {}. However, this means that the mapping function is not forced to return Fruit<apple>.

Additionally, if I specify mapping as:

mapping: () => T & {}

Then it works, and the mapping function must return a structure meeting the shape of Fruit<apple>.

If the appropriate generic types are explicitly provided, however, it also works. It just seems to try to best case guess T from all of its uses, and that best case almost always seems to be {} which means that this will always be broken...

Is this a problem related to the compiler picking the best common type/type inference for the generic, or am I wrong? (Also, sorry for opening so many issues recently, I'm building something new for work...)

@Roam-Cooper
Copy link
Author

Found that this is related to #5254

@Roam-Cooper
Copy link
Author

I feel like the only way to solve this is something like

let a: {} = { b: 1 };

Causing the error: { b: 1 } is not assignable to {} because b: number does not exist on {}
But I have a funny feeling that this is already "working as intended"...

@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2017

But I have a funny feeling that this is already "working as intended"...

yup. unfortunately , a type with no members ( i.e. {}), is a super type of all types. more in https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-all-types-assignable-to-empty-interfaces

@mhegazy mhegazy added the Working as Intended The behavior described is the intended behavior; this is not a bug label Apr 26, 2017
@mhegazy mhegazy closed this as completed May 17, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants