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

Don't widen inferred return types when a contextual signature is available #40311

Closed
wants to merge 6 commits into from

Conversation

DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Aug 29, 2020

Background

This PR has two high-level objectives:

  • to avoid anys in type argument inference outside of strictNullChecks
  • to ensure that excess property checks are more broadly applied in callback return positions

This PR achieves it by avoiding widening return types for function expressions that have been inferred from the body in cases where the current function has a contextual signature.

Widening Poisoning Inference With any

declare function pickRandom<T>(f: () => T, g: () => T): T;

// Returned type is `any`
pickRandom(() => 1, () => null);

Here, we have two function expressions passed into pickRandom. As it currently behaves, TypeScript will try to figure out the type of each function from its body, and in the function () => null, it will find the type null. Outside of strictNullChecks, the type system then widens that null to any. When it has to infer a type for T, it finds the candidates number and any, which just becomes any. This is a result of widening too early, and it's undesirable to let any absorb the number type instead of letting the number type absorb the null type.

Note that that function's return type isn't an implicit any because the function has a contextual signature (i.e. it's being contextually typed). We make an exception in this case. The rationale for that behavior is that it makes very little sense in many cases to issue an implicit any error when there's a contextual type and we know that the any isn't going to escape; however, in the presence of generics, that any does escape.

This behavior is bad, but it's not as bad as it used to be because we live in a world with strictNullChecks.

No Excess Property Checking

Today, if you have the following

interface Options {
    foo?: string,
    bar?: string,
}

declare function config(getOpts: () => Options): void;

// This errors.
let opts: Options = {
    foo: "hallo",
    ba: "oh no",
};

// This doesn't error.
config(() => ({
    foo: "hallo",
    ba: "oh no",
}));

Here, TypeScript gives an excess property error on the assignment to opts, but not within the callback to config.

The reason is that when it has to infer the type for () => ({ foo: "hallo", ba: "oh no", }), it picks up a fresh object type for { foo: "hallo", ba: "oh no", } as an initial candidate, and then widens that to its non-fresh version; however, freshness determines whether excess property checks are performed when determining compatibility against Options. This is another result of widening too early.

This seems to be the behavior most users we've heard are concerned with, which makes sense because users concerned with stricter checks might be the type to opt themselves into strictNullChecks.

Proposal

The proposal here is to only widen return types for function expressions when there is no contextual signature. The same is proposed for yielded and next'd types for generator expressions.

The key idea is that if a contextual type is found, we can be fairly sure that a return expression is going to need to be validated against that contextual type to some extent. In those cases, you really don't want to widen prematurely. In fact, this same logic is the reason we don't report a noImplicitAny.

Future Work

There are cases beyond checking whether there is no contextual signature (e.g. any argument position in a function call expression); however, those cases are no worse off than they are today.

interface Obj {
    a: string;
}

declare function foo(obj: Obj): void;
declare function foo(fn: () => Obj): void;

foo(() => ({ a: "hello", b: 123 })); // no error on 'b' - bad

There are also cases where we'll still widen too early at type argument inference.

function map<T, U>(xs: T[], f: (x: T) => U): U[];

interface Obj {
    a: string;
}
declare let stuff: string[];

let objs: Obj[] = map(stuff, _ => ({ a: "hello", b: 123 })); // no error on 'b' - bad

We can do better in both these cases in the future.

Relevant Issues

Fixes #241

Subsumes #20976

Duplicates

Fixes #7547
Fixes #20859
Fixes #27237
Fixes #28634
Fixes #30096
Fixes #30198
Fixes #31235
Fixes #12632
Fixes #11895
Fixes #33908
Fixes #37017
Fixes #39635
Fixes #40270
Fixes #40307

Probable Duplicates

I don't feel like installing React/React Native to test these.

Fixes #29390
Fixes #29499

Related But Not Fixed

Does not fix the following:

#7220
#10245 (comment)
#20008
#26999
#31425
#36053
#36354
#31254

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Aug 29, 2020
@DanielRosenwasser
Copy link
Member Author

@typescript-bot pack this
@typescript-bot test this
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this

@typescript-bot

This comment has been minimized.

@typescript-bot

This comment has been minimized.

@typescript-bot

This comment has been minimized.

@typescript-bot

This comment has been minimized.

@typescript-bot

This comment has been minimized.

@DanielRosenwasser DanielRosenwasser added the Experiment A fork with an experimental idea which might not make it into master label Aug 29, 2020
@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..40311

Metric master 40311 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 344,546k (± 0.02%) 344,589k (± 0.02%) +43k (+ 0.01%) 344,426k 344,697k
Parse Time 1.99s (± 0.49%) 2.00s (± 0.59%) +0.01s (+ 0.45%) 1.98s 2.02s
Bind Time 0.82s (± 0.68%) 0.82s (± 0.94%) -0.00s (- 0.12%) 0.81s 0.84s
Check Time 4.78s (± 0.66%) 4.79s (± 0.69%) +0.01s (+ 0.19%) 4.72s 4.89s
Emit Time 5.17s (± 0.53%) 5.16s (± 0.62%) -0.02s (- 0.31%) 5.11s 5.23s
Total Time 12.77s (± 0.29%) 12.77s (± 0.44%) +0.00s (+ 0.02%) 12.66s 12.92s
Monaco - node (v10.16.3, x64)
Memory used 339,408k (± 0.03%) 339,287k (± 0.04%) -122k (- 0.04%) 339,122k 339,623k
Parse Time 1.56s (± 0.49%) 1.55s (± 0.44%) -0.01s (- 0.58%) 1.53s 1.56s
Bind Time 0.72s (± 0.51%) 0.71s (± 0.73%) -0.01s (- 0.70%) 0.70s 0.72s
Check Time 4.97s (± 0.68%) 4.98s (± 0.63%) +0.01s (+ 0.14%) 4.91s 5.06s
Emit Time 2.75s (± 0.66%) 2.73s (± 0.61%) -0.02s (- 0.69%) 2.69s 2.76s
Total Time 10.00s (± 0.50%) 9.98s (± 0.42%) -0.03s (- 0.27%) 9.86s 10.04s
TFS - node (v10.16.3, x64)
Memory used 302,337k (± 0.04%) 302,400k (± 0.04%) +63k (+ 0.02%) 302,122k 302,649k
Parse Time 1.21s (± 0.72%) 1.21s (± 0.80%) +0.00s (+ 0.08%) 1.19s 1.24s
Bind Time 0.67s (± 1.26%) 0.67s (± 0.83%) -0.00s (- 0.45%) 0.65s 0.68s
Check Time 4.47s (± 0.91%) 4.47s (± 0.69%) -0.00s (- 0.02%) 4.41s 4.56s
Emit Time 2.92s (± 0.79%) 2.90s (± 1.08%) -0.02s (- 0.55%) 2.81s 2.97s
Total Time 9.26s (± 0.71%) 9.25s (± 0.60%) -0.02s (- 0.19%) 9.12s 9.41s
material-ui - node (v10.16.3, x64)
Memory used 461,337k (± 0.01%) 461,277k (± 0.02%) -60k (- 0.01%) 461,100k 461,408k
Parse Time 1.96s (± 0.51%) 1.95s (± 0.46%) -0.01s (- 0.31%) 1.93s 1.98s
Bind Time 0.66s (± 1.14%) 0.66s (± 1.05%) -0.01s (- 1.36%) 0.64s 0.67s
Check Time 13.52s (± 1.00%) 13.33s (± 0.64%) -0.20s (- 1.45%) 13.22s 13.62s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 16.15s (± 0.87%) 15.94s (± 0.55%) -0.21s (- 1.29%) 15.85s 16.25s
Angular - node (v12.1.0, x64)
Memory used 321,687k (± 0.03%) 321,696k (± 0.02%) +8k (+ 0.00%) 321,605k 321,885k
Parse Time 1.99s (± 0.78%) 1.99s (± 0.87%) -0.00s (- 0.10%) 1.96s 2.05s
Bind Time 0.81s (± 0.74%) 0.81s (± 0.59%) +0.00s (+ 0.25%) 0.80s 0.82s
Check Time 4.67s (± 0.46%) 4.68s (± 0.46%) +0.00s (+ 0.11%) 4.64s 4.72s
Emit Time 5.36s (± 1.08%) 5.33s (± 0.54%) -0.03s (- 0.60%) 5.28s 5.40s
Total Time 12.83s (± 0.37%) 12.81s (± 0.35%) -0.03s (- 0.23%) 12.72s 12.93s
Monaco - node (v12.1.0, x64)
Memory used 321,619k (± 0.01%) 321,605k (± 0.02%) -14k (- 0.00%) 321,509k 321,781k
Parse Time 1.53s (± 0.80%) 1.54s (± 0.70%) +0.01s (+ 0.78%) 1.52s 1.57s
Bind Time 0.69s (± 0.96%) 0.69s (± 0.83%) -0.00s (- 0.43%) 0.68s 0.70s
Check Time 4.77s (± 0.31%) 4.76s (± 0.49%) -0.01s (- 0.19%) 4.69s 4.81s
Emit Time 2.82s (± 0.90%) 2.79s (± 0.48%) -0.02s (- 0.85%) 2.77s 2.82s
Total Time 9.81s (± 0.31%) 9.78s (± 0.45%) -0.02s (- 0.25%) 9.68s 9.86s
TFS - node (v12.1.0, x64)
Memory used 286,688k (± 0.03%) 286,700k (± 0.03%) +12k (+ 0.00%) 286,524k 287,016k
Parse Time 1.23s (± 0.76%) 1.23s (± 0.50%) -0.00s (- 0.16%) 1.22s 1.24s
Bind Time 0.64s (± 1.09%) 0.65s (± 0.92%) +0.01s (+ 0.78%) 0.63s 0.66s
Check Time 4.36s (± 0.59%) 4.38s (± 0.46%) +0.02s (+ 0.53%) 4.34s 4.42s
Emit Time 2.92s (± 0.71%) 2.92s (± 0.77%) +0.00s (+ 0.00%) 2.88s 2.99s
Total Time 9.15s (± 0.48%) 9.18s (± 0.42%) +0.03s (+ 0.34%) 9.09s 9.27s
material-ui - node (v12.1.0, x64)
Memory used 439,707k (± 0.01%) 439,686k (± 0.01%) -21k (- 0.00%) 439,579k 439,847k
Parse Time 1.98s (± 0.53%) 1.98s (± 0.33%) +0.00s (+ 0.00%) 1.96s 1.99s
Bind Time 0.63s (± 0.91%) 0.63s (± 0.91%) 0.00s ( 0.00%) 0.62s 0.65s
Check Time 12.17s (± 1.26%) 11.95s (± 0.80%) -0.22s (- 1.79%) 11.77s 12.24s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 14.77s (± 1.06%) 14.55s (± 0.67%) -0.22s (- 1.49%) 14.37s 14.84s
Angular - node (v8.9.0, x64)
Memory used 341,102k (± 0.02%) 341,057k (± 0.02%) -45k (- 0.01%) 340,920k 341,224k
Parse Time 2.54s (± 0.58%) 2.54s (± 0.55%) -0.00s (- 0.12%) 2.51s 2.57s
Bind Time 0.85s (± 0.58%) 0.86s (± 0.85%) +0.01s (+ 1.42%) 0.84s 0.87s
Check Time 5.40s (± 0.48%) 5.44s (± 0.43%) +0.04s (+ 0.72%) 5.38s 5.50s
Emit Time 5.92s (± 0.49%) 6.01s (± 1.40%) +0.08s (+ 1.42%) 5.88s 6.22s
Total Time 14.72s (± 0.30%) 14.85s (± 0.61%) +0.13s (+ 0.88%) 14.71s 15.13s
Monaco - node (v8.9.0, x64)
Memory used 340,627k (± 0.01%) 340,643k (± 0.01%) +16k (+ 0.00%) 340,533k 340,724k
Parse Time 1.87s (± 0.41%) 1.88s (± 0.44%) +0.01s (+ 0.27%) 1.86s 1.89s
Bind Time 0.89s (± 0.56%) 0.88s (± 0.63%) -0.00s (- 0.45%) 0.87s 0.90s
Check Time 5.48s (± 0.53%) 5.50s (± 0.49%) +0.02s (+ 0.35%) 5.42s 5.55s
Emit Time 3.21s (± 0.58%) 3.23s (± 0.92%) +0.01s (+ 0.40%) 3.18s 3.34s
Total Time 11.45s (± 0.32%) 11.49s (± 0.43%) +0.04s (+ 0.32%) 11.39s 11.65s
TFS - node (v8.9.0, x64)
Memory used 303,971k (± 0.03%) 303,940k (± 0.02%) -31k (- 0.01%) 303,816k 304,030k
Parse Time 1.55s (± 0.57%) 1.55s (± 0.38%) -0.00s (- 0.26%) 1.53s 1.56s
Bind Time 0.68s (± 0.33%) 0.68s (± 0.88%) -0.00s (- 0.44%) 0.66s 0.69s
Check Time 5.22s (± 0.68%) 5.22s (± 0.73%) 0.00s ( 0.00%) 5.15s 5.31s
Emit Time 2.92s (± 0.94%) 2.94s (± 0.79%) +0.02s (+ 0.55%) 2.86s 2.98s
Total Time 10.37s (± 0.42%) 10.38s (± 0.51%) +0.01s (+ 0.12%) 10.27s 10.49s
material-ui - node (v8.9.0, x64)
Memory used 465,698k (± 0.01%) 465,640k (± 0.01%) -58k (- 0.01%) 465,498k 465,733k
Parse Time 2.38s (± 0.47%) 2.39s (± 0.64%) +0.01s (+ 0.42%) 2.36s 2.42s
Bind Time 0.78s (± 1.65%) 0.78s (± 1.20%) -0.00s (- 0.38%) 0.76s 0.80s
Check Time 17.87s (± 1.28%) 17.87s (± 0.81%) +0.00s (+ 0.01%) 17.58s 18.14s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 21.03s (± 1.08%) 21.04s (± 0.65%) +0.01s (+ 0.04%) 20.74s 21.32s
Angular - node (v8.9.0, x86)
Memory used 195,669k (± 0.02%) 195,711k (± 0.01%) +42k (+ 0.02%) 195,653k 195,769k
Parse Time 2.46s (± 0.72%) 2.47s (± 0.60%) +0.01s (+ 0.45%) 2.43s 2.49s
Bind Time 0.99s (± 0.60%) 0.99s (± 0.77%) -0.00s (- 0.10%) 0.97s 1.00s
Check Time 4.90s (± 0.44%) 4.88s (± 0.75%) -0.01s (- 0.27%) 4.81s 4.95s
Emit Time 5.91s (± 0.73%) 5.94s (± 0.70%) +0.04s (+ 0.64%) 5.85s 6.07s
Total Time 14.24s (± 0.28%) 14.28s (± 0.43%) +0.03s (+ 0.23%) 14.13s 14.42s
Monaco - node (v8.9.0, x86)
Memory used 193,655k (± 0.01%) 193,689k (± 0.01%) +34k (+ 0.02%) 193,607k 193,742k
Parse Time 1.90s (± 0.53%) 1.91s (± 0.94%) +0.00s (+ 0.05%) 1.88s 1.95s
Bind Time 0.70s (± 0.82%) 0.70s (± 0.67%) -0.00s (- 0.00%) 0.69s 0.71s
Check Time 5.60s (± 1.21%) 5.61s (± 0.44%) +0.01s (+ 0.21%) 5.56s 5.66s
Emit Time 2.71s (± 2.76%) 2.65s (± 0.51%) -0.06s (- 2.28%) 2.62s 2.69s
Total Time 10.92s (± 0.47%) 10.87s (± 0.35%) -0.05s (- 0.46%) 10.79s 10.97s
TFS - node (v8.9.0, x86)
Memory used 173,889k (± 0.04%) 173,877k (± 0.02%) -13k (- 0.01%) 173,824k 173,935k
Parse Time 1.59s (± 1.11%) 1.58s (± 0.81%) -0.00s (- 0.25%) 1.56s 1.62s
Bind Time 0.65s (± 1.72%) 0.64s (± 0.46%) -0.00s (- 0.62%) 0.64s 0.65s
Check Time 4.73s (± 0.66%) 4.70s (± 0.37%) -0.03s (- 0.57%) 4.67s 4.74s
Emit Time 2.80s (± 1.40%) 2.79s (± 1.10%) -0.01s (- 0.29%) 2.71s 2.87s
Total Time 9.76s (± 0.56%) 9.72s (± 0.44%) -0.05s (- 0.47%) 9.64s 9.80s
material-ui - node (v8.9.0, x86)
Memory used 263,677k (± 0.01%) 263,694k (± 0.01%) +17k (+ 0.01%) 263,616k 263,765k
Parse Time 2.44s (± 0.74%) 2.44s (± 0.79%) -0.00s (- 0.12%) 2.41s 2.50s
Bind Time 0.68s (± 1.92%) 0.68s (± 0.85%) +0.00s (+ 0.15%) 0.67s 0.69s
Check Time 16.59s (± 0.56%) 16.29s (± 0.34%) -0.30s (- 1.78%) 16.15s 16.41s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 19.71s (± 0.50%) 19.42s (± 0.30%) -0.30s (- 1.50%) 19.26s 19.58s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-166-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 40311 10
Baseline master 10

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Aug 29, 2020

Early results:


We correctly issue excess property errors as expected. In some cases, we switch from missing property errors to excess property errors.

e9b467a#diff-0e97ff0d65c086767a3444a59e9b9e28


We issue one new implicit any error!

e9b467a#diff-5a40e91166140ce9c4dc158237e985f1


This seems to have reverted a regression introduced in #29478, and explained in #29478 (comment). I don't really know why this fixes things, but my guess is that we are a little bit more lax about finding the best common type in fresh object types:

e9b467a#diff-87ebcaa183574f2823b6ee03abb3316b


In TSServer itself, we seem to have caught a bug where we weren't correctly including a source property in DiagnosticWithLinePosition (or we were incorrectly providing it).

src/server/session.ts(1123,17): error TS2322: Type '{ message: string; start: number; length: number; category: string; code: number; source: string | undefined; startLocation: protocol.Location; endLocation: protocol.Location; reportsUnnecessary: {} | undefined; reportsDeprecated: {} | undefined; relatedInformation: protocol.DiagnosticRelatedInformation[] | undefine...' is not assignable to type 'DiagnosticWithLinePosition'.
  Object literal may only specify known properties, and 'source' does not exist in type 'DiagnosticWithLinePosition'.

https://github.com/microsoft/TypeScript/runs/1043841312#step:7:137

https://typescript.visualstudio.com/TypeScript/_build/results?buildId=83662&view=logs&j=fd490c07-0b22-5182-fac9-6d67fe1e939b&t=cb364164-b022-581f-97fd-158a20e3d408&l=178


It's unclear whether there's actually a speedup in check-time on material-ui because it's so noisy, but I thought that might be worth mentioning.

@DanielRosenwasser
Copy link
Member Author

@typescript-bot pack this
@typescript-bot test this
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 29, 2020

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 4f30b40. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 29, 2020

Heya @DanielRosenwasser, I've started to run the perf test suite on this PR at 4f30b40. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 29, 2020

Heya @DanielRosenwasser, I've started to run the extended test suite on this PR at 4f30b40. You can monitor the build here.

@typescript-bot

This comment has been minimized.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 29, 2020

Heya @DanielRosenwasser, I've started to run the parallelized Definitely Typed test suite on this PR at 4f30b40. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/83695/artifacts?artifactName=tgz&fileId=0A3E072802E458145BBA5B36AA37AABE4FB300F7BBD3A55715AA9AA077F8D69F02&fileName=/typescript-4.1.0-insiders.20200829.tgz"
    }
}

and then running npm install.

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Aug 29, 2020

One deficiency that I've noticed is that this doesn't work well in the presence of overloads.

interface Obj {
    a: string;
}

declare function foo(obj: Obj): void;
declare function foo(fn: () => Obj): void;

foo(() => ({ a: "hello", b: 123 }))

Right now this doesn't error under this PR (which is bad). Remove the first overload, and you'll an error (which is good).

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..40311

Metric master 40311 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 344,479k (± 0.02%) 344,619k (± 0.03%) +140k (+ 0.04%) 344,444k 344,774k
Parse Time 2.00s (± 0.51%) 1.99s (± 0.45%) -0.01s (- 0.35%) 1.97s 2.01s
Bind Time 0.82s (± 0.70%) 0.82s (± 1.52%) +0.00s (+ 0.49%) 0.80s 0.87s
Check Time 4.76s (± 0.32%) 4.80s (± 0.70%) +0.04s (+ 0.84%) 4.75s 4.90s
Emit Time 5.17s (± 0.67%) 5.17s (± 0.49%) +0.00s (+ 0.04%) 5.12s 5.22s
Total Time 12.75s (± 0.39%) 12.78s (± 0.27%) +0.04s (+ 0.28%) 12.73s 12.85s
Monaco - node (v10.16.3, x64)
Memory used 339,354k (± 0.02%) 339,394k (± 0.04%) +39k (+ 0.01%) 339,215k 339,756k
Parse Time 1.54s (± 0.44%) 1.55s (± 0.48%) +0.00s (+ 0.19%) 1.53s 1.56s
Bind Time 0.71s (± 0.48%) 0.71s (± 0.83%) +0.00s (+ 0.14%) 0.70s 0.73s
Check Time 4.96s (± 0.73%) 4.96s (± 0.67%) +0.00s (+ 0.00%) 4.88s 5.03s
Emit Time 2.73s (± 0.33%) 2.74s (± 0.53%) +0.01s (+ 0.26%) 2.70s 2.78s
Total Time 9.95s (± 0.39%) 9.96s (± 0.34%) +0.02s (+ 0.16%) 9.90s 10.05s
TFS - node (v10.16.3, x64)
Memory used 302,328k (± 0.03%) 302,356k (± 0.03%) +29k (+ 0.01%) 302,043k 302,519k
Parse Time 1.20s (± 0.51%) 1.21s (± 0.56%) +0.01s (+ 0.42%) 1.19s 1.22s
Bind Time 0.66s (± 1.74%) 0.67s (± 1.30%) +0.01s (+ 0.75%) 0.65s 0.69s
Check Time 4.47s (± 0.58%) 4.50s (± 0.59%) +0.03s (+ 0.69%) 4.44s 4.58s
Emit Time 2.90s (± 1.04%) 2.91s (± 1.21%) +0.01s (+ 0.17%) 2.84s 2.96s
Total Time 9.24s (± 0.40%) 9.28s (± 0.68%) +0.05s (+ 0.49%) 9.18s 9.42s
material-ui - node (v10.16.3, x64)
Memory used 461,311k (± 0.01%) 461,289k (± 0.01%) -23k (- 0.00%) 461,163k 461,426k
Parse Time 1.95s (± 0.32%) 1.95s (± 0.34%) +0.00s (+ 0.21%) 1.94s 1.97s
Bind Time 0.65s (± 1.35%) 0.66s (± 0.84%) +0.01s (+ 1.38%) 0.65s 0.67s
Check Time 13.34s (± 0.37%) 13.40s (± 0.73%) +0.06s (+ 0.43%) 13.27s 13.72s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.94s (± 0.34%) 16.01s (± 0.62%) +0.07s (+ 0.43%) 15.88s 16.33s
Angular - node (v12.1.0, x64)
Memory used 321,776k (± 0.03%) 321,804k (± 0.03%) +28k (+ 0.01%) 321,617k 321,963k
Parse Time 1.98s (± 0.69%) 1.99s (± 0.54%) +0.00s (+ 0.25%) 1.97s 2.02s
Bind Time 0.81s (± 0.69%) 0.81s (± 0.80%) -0.00s (- 0.00%) 0.80s 0.82s
Check Time 4.66s (± 0.48%) 4.68s (± 0.54%) +0.03s (+ 0.56%) 4.63s 4.74s
Emit Time 5.31s (± 0.53%) 5.34s (± 0.67%) +0.03s (+ 0.62%) 5.28s 5.45s
Total Time 12.75s (± 0.36%) 12.82s (± 0.50%) +0.07s (+ 0.53%) 12.68s 13.00s
Monaco - node (v12.1.0, x64)
Memory used 321,640k (± 0.02%) 321,660k (± 0.02%) +20k (+ 0.01%) 321,528k 321,823k
Parse Time 1.51s (± 0.54%) 1.53s (± 0.80%) +0.02s (+ 1.19%) 1.50s 1.55s
Bind Time 0.69s (± 0.81%) 0.69s (± 0.32%) +0.00s (+ 0.44%) 0.69s 0.70s
Check Time 4.74s (± 0.35%) 4.77s (± 0.68%) +0.03s (+ 0.65%) 4.73s 4.85s
Emit Time 2.78s (± 0.40%) 2.81s (± 0.81%) +0.02s (+ 0.79%) 2.77s 2.88s
Total Time 9.72s (± 0.23%) 9.80s (± 0.42%) +0.08s (+ 0.77%) 9.72s 9.87s
TFS - node (v12.1.0, x64)
Memory used 286,651k (± 0.04%) 286,710k (± 0.02%) +60k (+ 0.02%) 286,592k 286,812k
Parse Time 1.23s (± 0.76%) 1.23s (± 0.50%) -0.00s (- 0.08%) 1.22s 1.25s
Bind Time 0.64s (± 0.62%) 0.64s (± 1.44%) +0.00s (+ 0.16%) 0.62s 0.66s
Check Time 4.36s (± 0.41%) 4.35s (± 0.46%) -0.01s (- 0.25%) 4.29s 4.38s
Emit Time 2.92s (± 0.60%) 2.91s (± 1.06%) -0.01s (- 0.27%) 2.83s 2.98s
Total Time 9.14s (± 0.25%) 9.13s (± 0.40%) -0.02s (- 0.19%) 9.05s 9.22s
material-ui - node (v12.1.0, x64)
Memory used 439,532k (± 0.07%) 439,563k (± 0.04%) +31k (+ 0.01%) 438,786k 439,744k
Parse Time 1.98s (± 0.61%) 1.97s (± 0.51%) -0.01s (- 0.25%) 1.94s 1.99s
Bind Time 0.63s (± 1.03%) 0.63s (± 0.75%) +0.00s (+ 0.32%) 0.62s 0.64s
Check Time 11.96s (± 0.55%) 12.03s (± 0.76%) +0.06s (+ 0.54%) 11.86s 12.25s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 14.57s (± 0.46%) 14.63s (± 0.68%) +0.06s (+ 0.41%) 14.44s 14.86s
Angular - node (v8.9.0, x64)
Memory used 341,064k (± 0.02%) 341,125k (± 0.02%) +60k (+ 0.02%) 341,006k 341,244k
Parse Time 2.54s (± 0.44%) 2.54s (± 0.39%) -0.01s (- 0.28%) 2.52s 2.57s
Bind Time 0.85s (± 0.61%) 0.85s (± 0.55%) +0.00s (+ 0.12%) 0.84s 0.86s
Check Time 5.41s (± 0.69%) 5.43s (± 0.46%) +0.02s (+ 0.31%) 5.38s 5.50s
Emit Time 5.93s (± 2.10%) 5.93s (± 1.41%) -0.01s (- 0.10%) 5.72s 6.11s
Total Time 14.74s (± 0.96%) 14.75s (± 0.68%) +0.00s (+ 0.02%) 14.55s 15.00s
Monaco - node (v8.9.0, x64)
Memory used 340,670k (± 0.02%) 340,684k (± 0.01%) +14k (+ 0.00%) 340,590k 340,754k
Parse Time 1.87s (± 0.28%) 1.88s (± 0.37%) +0.01s (+ 0.43%) 1.86s 1.90s
Bind Time 0.89s (± 0.54%) 0.89s (± 0.42%) -0.00s (- 0.23%) 0.88s 0.89s
Check Time 5.46s (± 0.68%) 5.51s (± 0.45%) +0.05s (+ 0.88%) 5.47s 5.58s
Emit Time 3.21s (± 0.96%) 3.21s (± 0.57%) -0.00s (- 0.09%) 3.18s 3.27s
Total Time 11.43s (± 0.48%) 11.48s (± 0.33%) +0.05s (+ 0.42%) 11.40s 11.57s
TFS - node (v8.9.0, x64)
Memory used 303,961k (± 0.01%) 303,902k (± 0.02%) -59k (- 0.02%) 303,820k 304,031k
Parse Time 1.55s (± 0.54%) 1.54s (± 0.31%) -0.00s (- 0.13%) 1.53s 1.55s
Bind Time 0.67s (± 0.66%) 0.67s (± 1.04%) -0.00s (- 0.15%) 0.66s 0.69s
Check Time 5.18s (± 0.56%) 5.20s (± 0.54%) +0.02s (+ 0.39%) 5.13s 5.26s
Emit Time 2.92s (± 0.87%) 2.92s (± 0.87%) +0.00s (+ 0.07%) 2.84s 2.96s
Total Time 10.32s (± 0.44%) 10.34s (± 0.52%) +0.02s (+ 0.17%) 10.17s 10.45s
material-ui - node (v8.9.0, x64)
Memory used 465,671k (± 0.01%) 465,680k (± 0.01%) +10k (+ 0.00%) 465,626k 465,776k
Parse Time 2.38s (± 0.40%) 2.40s (± 0.81%) +0.02s (+ 0.84%) 2.36s 2.46s
Bind Time 0.78s (± 1.28%) 0.79s (± 0.82%) +0.00s (+ 0.51%) 0.77s 0.80s
Check Time 18.00s (± 0.79%) 17.93s (± 1.10%) -0.07s (- 0.39%) 17.52s 18.40s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 21.16s (± 0.69%) 21.12s (± 0.91%) -0.05s (- 0.22%) 20.71s 21.57s
Angular - node (v8.9.0, x86)
Memory used 195,721k (± 0.02%) 195,677k (± 0.02%) -44k (- 0.02%) 195,587k 195,755k
Parse Time 2.43s (± 0.30%) 2.47s (± 0.70%) +0.03s (+ 1.40%) 2.42s 2.50s
Bind Time 0.99s (± 0.59%) 1.00s (± 0.60%) +0.01s (+ 0.91%) 0.98s 1.01s
Check Time 4.88s (± 0.54%) 4.88s (± 0.53%) +0.00s (+ 0.06%) 4.84s 4.94s
Emit Time 5.97s (± 1.80%) 5.96s (± 1.17%) -0.01s (- 0.23%) 5.83s 6.17s
Total Time 14.27s (± 0.86%) 14.30s (± 0.50%) +0.03s (+ 0.21%) 14.13s 14.47s
Monaco - node (v8.9.0, x86)
Memory used 193,666k (± 0.01%) 193,667k (± 0.03%) +1k (+ 0.00%) 193,554k 193,776k
Parse Time 1.91s (± 1.24%) 1.91s (± 0.79%) -0.00s (- 0.10%) 1.88s 1.95s
Bind Time 0.70s (± 0.88%) 0.70s (± 0.68%) -0.00s (- 0.29%) 0.69s 0.71s
Check Time 5.59s (± 1.22%) 5.58s (± 0.56%) -0.02s (- 0.32%) 5.50s 5.65s
Emit Time 2.69s (± 2.98%) 2.66s (± 1.06%) -0.03s (- 1.04%) 2.62s 2.74s
Total Time 10.89s (± 0.46%) 10.84s (± 0.32%) -0.06s (- 0.51%) 10.77s 10.92s
TFS - node (v8.9.0, x86)
Memory used 173,892k (± 0.03%) 173,876k (± 0.02%) -17k (- 0.01%) 173,787k 173,980k
Parse Time 1.58s (± 0.65%) 1.58s (± 0.60%) +0.00s (+ 0.19%) 1.56s 1.61s
Bind Time 0.65s (± 1.38%) 0.65s (± 1.63%) +0.00s (+ 0.15%) 0.63s 0.68s
Check Time 4.68s (± 0.47%) 4.72s (± 0.61%) +0.05s (+ 1.01%) 4.67s 4.80s
Emit Time 2.77s (± 0.99%) 2.80s (± 1.32%) +0.03s (+ 1.26%) 2.75s 2.92s
Total Time 9.67s (± 0.31%) 9.76s (± 0.47%) +0.09s (+ 0.90%) 9.67s 9.86s
material-ui - node (v8.9.0, x86)
Memory used 263,649k (± 0.02%) 263,681k (± 0.02%) +32k (+ 0.01%) 263,596k 263,751k
Parse Time 2.43s (± 0.41%) 2.45s (± 0.56%) +0.02s (+ 0.82%) 2.42s 2.48s
Bind Time 0.67s (± 1.38%) 0.68s (± 1.77%) +0.01s (+ 0.74%) 0.66s 0.71s
Check Time 16.47s (± 0.68%) 16.44s (± 0.91%) -0.03s (- 0.19%) 16.25s 16.80s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 19.58s (± 0.58%) 19.57s (± 0.77%) -0.02s (- 0.08%) 19.34s 19.95s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-166-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 40311 10
Baseline master 10

@DanielRosenwasser DanielRosenwasser changed the title Don't widen inferred return types when a contextual type is available Don't widen inferred return types when a contextual signature is available Aug 31, 2020
@DanielRosenwasser
Copy link
Member Author

@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 31, 2020

Heya @DanielRosenwasser, I've started to run the parallelized community code test suite on this PR at 4f30b40. You can monitor the build here.

@DanielRosenwasser DanielRosenwasser removed the Experiment A fork with an experimental idea which might not make it into master label Sep 2, 2020
@typescript-bot
Copy link
Collaborator

typescript-bot commented Sep 4, 2020

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/84231/artifacts?artifactName=tgz&fileId=C84DB49EF41CE2A07C073835B44DCE033C5DD3BE0AB4AEBC5542FBABAD1F9E9702&fileName=/typescript-4.1.0-insiders.20200904.tgz"
    }
}

and then running npm install.


There is also a playground for this build.

@@ -511,6 +511,7 @@ namespace ts.server.protocol {
endLocation: Location;
category: string;
code: number;
source?: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change unrelated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think @sheetalkamat might have a better idea, but this un-breaks an excess property error we had in the server layer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#15296 added this so diagnostics origin can be distinguished.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still a bit wary that this is ad-hoc and will cause either confusion in the form of subtle by-design bugs.

But it does what what we agreed on at the design meeting.


==== tests/cases/conformance/types/tuple/wideningTuples2.ts (1 errors) ====
var foo: () => [any] = function bar() {
let intermediate = bar();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as stated in the meeting I do think this is not a reasonable new error in a quite old test (and was dealt with in the prior iteration of this change), and this can be somewhat easily avoided by using the old behavior for named function expressions (which are generally only used when you want recursive references like this anyhow). A self-call witnessing the unwidened type is very odd, given our widening rules (no exterior calls can witness the unwidened type). I think this can manifest in even stranger behavior if you do something with the bar reference rather than just call it - like pass it into a function desiring a callback, eg handle(bar) where declare function handle(a: () => [any]): void, or worse yet declare function handle<T>(a: T): T where the unwidened type will simply propagate via inference - where then you'll get this widening error so far removed from anything that it's relevant to that it's quite clear something's gone wrong.

@lauchlan105
Copy link

Is merging this still a possibility or will this PR ultimately be abandoned?

@typescript-bot
Copy link
Collaborator

The TypeScript team hasn't accepted the linked issue #241. If you can get it accepted, this PR will have a better chance of being reviewed.

@sandersn
Copy link
Member

@DanielRosenwasser is this change still worth taking? If so, can you address @weswigham's idea for named functions?

@mrlubos
Copy link

mrlubos commented May 17, 2021

Hey everyone, is this pull request still on track to land any time soon?

@sandersn
Copy link
Member

This PR hasn't seen any activity for quite a while, so I'm going to close it to keep the number of open PRs manageable.

@sandersn sandersn closed this Aug 20, 2021
@thw0rted
Copy link

@DanielRosenwasser @sandersn I just skimmed the history here and it looks like this implements fixes for a large number of issues, including one that's over 7 years old (filed by @RyanCavanaugh , with 58 upvotes). As far as I can tell the only thing that prevented merging was #40311 (comment) , but there was no further discussion about whether this would be easy to fix.

Is my assessment accurate? Is this likely to get picked back up at some later point by the current triage process?

@sandersn
Copy link
Member

Looking at the history, it seems like @DanielRosenwasser and @weswigham disagreed about the outcome of a design meeting. My guess is that we should bring it up there again. It's up to @DanielRosenwasser though, since he wrote the code and puts together the agenda.

@mogelbrod
Copy link

mogelbrod commented Sep 16, 2021

Linking to a relevant StackOverflow question that would've been solved by this PR - I've yet to find any alternative solutions to this. Related test in the typescript playground.

@JGJP
Copy link

JGJP commented Oct 26, 2022

@DanielRosenwasser @sandersn it is now a year later, was this brought up for discussion internally? What will it take to get this resolved?

@yamcodes
Copy link

We've encountered this issue many times before and would love this fix to be included in the next TypeScript release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment