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

wrong type infer in 3.6.0-dev.20190725 #32572

Closed
bluelovers opened this issue Jul 26, 2019 · 2 comments · Fixed by #32558
Closed

wrong type infer in 3.6.0-dev.20190725 #32572

bluelovers opened this issue Jul 26, 2019 · 2 comments · Fixed by #32558
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@bluelovers
Copy link
Contributor

TypeScript Version: 3.4.0-dev.201xxxxx

Search Terms:

Code

this code work at 3.5.2 and 3.6.0-dev.20190704

but fail at 3.6.0-dev.20190725

import Bluebird = require('bluebird');

let a: string[] = [];

Bluebird.resolve(a as string[])
	.mapSeries(async function (vvvv)
	{
		console.log(vvvv.toUpperCase())

		return vvvv;
	})
;

Bluebird.resolve(a as string[])
	.mapSeries(function (vvvv)
	{
		console.log(vvvv.toUpperCase())

		return vvvv;
	})
;

Bluebird.resolve(a as string[])
	.mapSeries((vvvv) =>
	{
		console.log(vvvv.toUpperCase())

		return vvvv;
	})
;

Expected behavior:

no error and infer to string

Actual behavior:

vvvv infer to unknown

image

Playground Link:

Related Issues:

@jcalz
Copy link
Contributor

jcalz commented Jul 26, 2019

Ideally bug reports will have a completely self-contained example that you don't need external libraries to reproduce. Like maybe this:

interface Prom<T> {
  mapSeries<Q>(
    this: Prom<T & Iterable<Q>>,
    iterator: (item: Q) => any
  ): any;
}

declare const p: Prom<string[]>;

p.mapSeries(async function (s) {
  console.log(s.toUpperCase()); // error, s is unknown 3.6.0-dev.20190725
});

Playground (but there's no error in v3.5.1)

Something about this and not being able to infer Q from the type T & Iterable<Q> in this scenario. (Workaround: replace Q with or constrain Q to (T extends Iterable<infer I> ? I : never))

Not sure if this is really a bug or what. Seems like it might be a breaking change for Bluebird, though.

Caused by #32386/#32460? (🃏wild guess❓)

@ahejlsberg
Copy link
Member

This is caused by #32460. Consider the following simplified example:

declare function foo1<T>(obj: string[] & Iterable<T>): T;
declare function foo2<T>(obj: string[] & T): T;

declare let sa: string[];
declare let sx: string[] & { extra: number };

let x1 = foo1(sa);
let y1 = foo1(sx);

let x2 = foo2(sa);
let y2 = foo2(sx);

With 3.5.x we produced the following results:

let x1 = foo1(sa);  // string
let y1 = foo1(sx);  // unknown

let x2 = foo2(sa);  // string[]
let y2 = foo2(sx);  // { extra: number }

It's pretty clear that x1 and y2 are inconsistent, and unknown would be a better inference for x2.

With 3.6.0-dev.20190725 we produce:

let x1 = foo1(sa);  // unknown
let y1 = foo1(sx);  // unknown

let x2 = foo2(sa);  // unknown
let y2 = foo2(sx);  // { extra: number }

This has the better inference for x2 and it makes x1 and y1 consistent, but unknown is really not a good inference here. I think the desired outcome is:

let x1 = foo1(sa);  // string
let y1 = foo1(sx);  // string

let x2 = foo2(sa);  // unknown
let y2 = foo2(sx);  // { extra: number }

I have updated #32558 to implement this and I'm currently checking for effects on the DT tests.

@ahejlsberg ahejlsberg self-assigned this Jul 26, 2019
@ahejlsberg ahejlsberg added the Bug A bug in TypeScript label Jul 26, 2019
@ahejlsberg ahejlsberg added this to the TypeScript 3.6.1 milestone Jul 26, 2019
@ahejlsberg ahejlsberg added the Fix Available A PR has been opened for this issue label Jul 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants