Skip to content

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

Closed
Daniel Rosenwasser (DanielRosenwasser) wants to merge 6 commits into
mainfrom
avoidWidenedReturnTypes
Closed

Don't widen inferred return types when a contextual signature is available#40311
Daniel Rosenwasser (DanielRosenwasser) wants to merge 6 commits into
mainfrom
avoidWidenedReturnTypes

Conversation

@DanielRosenwasser

@DanielRosenwasserDaniel Rosenwasser (DanielRosenwasser) commented Aug 29, 2020

Copy link
Copy Markdown
Member

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

declarefunctionpickRandom<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 anydoes 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

interfaceOptions{foo?: string,bar?: string,}declarefunctionconfig(getOpts: ()=>Options): void;// This errors.letopts: 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.

interfaceObj{a: string;}declarefunctionfoo(obj: Obj): void;declarefunctionfoo(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.

functionmap<T,U>(xs: T[],f: (x: T)=>U): U[];interfaceObj{a: string;}declareletstuff: string[];letobjs: 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-botTypeScript Bot (typescript-bot) added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Aug 29, 2020
@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

@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.

@DanielRosenwasserDaniel Rosenwasser (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
Copy Markdown
Contributor

Daniel Rosenwasser (@DanielRosenwasser)
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..40311

Metricmaster40311DeltaBestWorst
Angular - node (v10.16.3, x64)
Memory used344,546k (± 0.02%)344,589k (± 0.02%)+43k (+ 0.01%)344,426k344,697k
Parse Time1.99s (± 0.49%)2.00s (± 0.59%)+0.01s (+ 0.45%)1.98s2.02s
Bind Time0.82s (± 0.68%)0.82s (± 0.94%)-0.00s (- 0.12%)0.81s0.84s
Check Time4.78s (± 0.66%)4.79s (± 0.69%)+0.01s (+ 0.19%)4.72s4.89s
Emit Time5.17s (± 0.53%)5.16s (± 0.62%)-0.02s (- 0.31%)5.11s5.23s
Total Time12.77s (± 0.29%)12.77s (± 0.44%)+0.00s (+ 0.02%)12.66s12.92s
Monaco - node (v10.16.3, x64)
Memory used339,408k (± 0.03%)339,287k (± 0.04%)-122k (- 0.04%)339,122k339,623k
Parse Time1.56s (± 0.49%)1.55s (± 0.44%)-0.01s (- 0.58%)1.53s1.56s
Bind Time0.72s (± 0.51%)0.71s (± 0.73%)-0.01s (- 0.70%)0.70s0.72s
Check Time4.97s (± 0.68%)4.98s (± 0.63%)+0.01s (+ 0.14%)4.91s5.06s
Emit Time2.75s (± 0.66%)2.73s (± 0.61%)-0.02s (- 0.69%)2.69s2.76s
Total Time10.00s (± 0.50%)9.98s (± 0.42%)-0.03s (- 0.27%)9.86s10.04s
TFS - node (v10.16.3, x64)
Memory used302,337k (± 0.04%)302,400k (± 0.04%)+63k (+ 0.02%)302,122k302,649k
Parse Time1.21s (± 0.72%)1.21s (± 0.80%)+0.00s (+ 0.08%)1.19s1.24s
Bind Time0.67s (± 1.26%)0.67s (± 0.83%)-0.00s (- 0.45%)0.65s0.68s
Check Time4.47s (± 0.91%)4.47s (± 0.69%)-0.00s (- 0.02%)4.41s4.56s
Emit Time2.92s (± 0.79%)2.90s (± 1.08%)-0.02s (- 0.55%)2.81s2.97s
Total Time9.26s (± 0.71%)9.25s (± 0.60%)-0.02s (- 0.19%)9.12s9.41s
material-ui - node (v10.16.3, x64)
Memory used461,337k (± 0.01%)461,277k (± 0.02%)-60k (- 0.01%)461,100k461,408k
Parse Time1.96s (± 0.51%)1.95s (± 0.46%)-0.01s (- 0.31%)1.93s1.98s
Bind Time0.66s (± 1.14%)0.66s (± 1.05%)-0.01s (- 1.36%)0.64s0.67s
Check Time13.52s (± 1.00%)13.33s (± 0.64%)-0.20s (- 1.45%)13.22s13.62s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time16.15s (± 0.87%)15.94s (± 0.55%)-0.21s (- 1.29%)15.85s16.25s
Angular - node (v12.1.0, x64)
Memory used321,687k (± 0.03%)321,696k (± 0.02%)+8k (+ 0.00%)321,605k321,885k
Parse Time1.99s (± 0.78%)1.99s (± 0.87%)-0.00s (- 0.10%)1.96s2.05s
Bind Time0.81s (± 0.74%)0.81s (± 0.59%)+0.00s (+ 0.25%)0.80s0.82s
Check Time4.67s (± 0.46%)4.68s (± 0.46%)+0.00s (+ 0.11%)4.64s4.72s
Emit Time5.36s (± 1.08%)5.33s (± 0.54%)-0.03s (- 0.60%)5.28s5.40s
Total Time12.83s (± 0.37%)12.81s (± 0.35%)-0.03s (- 0.23%)12.72s12.93s
Monaco - node (v12.1.0, x64)
Memory used321,619k (± 0.01%)321,605k (± 0.02%)-14k (- 0.00%)321,509k321,781k
Parse Time1.53s (± 0.80%)1.54s (± 0.70%)+0.01s (+ 0.78%)1.52s1.57s
Bind Time0.69s (± 0.96%)0.69s (± 0.83%)-0.00s (- 0.43%)0.68s0.70s
Check Time4.77s (± 0.31%)4.76s (± 0.49%)-0.01s (- 0.19%)4.69s4.81s
Emit Time2.82s (± 0.90%)2.79s (± 0.48%)-0.02s (- 0.85%)2.77s2.82s
Total Time9.81s (± 0.31%)9.78s (± 0.45%)-0.02s (- 0.25%)9.68s9.86s
TFS - node (v12.1.0, x64)
Memory used286,688k (± 0.03%)286,700k (± 0.03%)+12k (+ 0.00%)286,524k287,016k
Parse Time1.23s (± 0.76%)1.23s (± 0.50%)-0.00s (- 0.16%)1.22s1.24s
Bind Time0.64s (± 1.09%)0.65s (± 0.92%)+0.01s (+ 0.78%)0.63s0.66s
Check Time4.36s (± 0.59%)4.38s (± 0.46%)+0.02s (+ 0.53%)4.34s4.42s
Emit Time2.92s (± 0.71%)2.92s (± 0.77%)+0.00s (+ 0.00%)2.88s2.99s
Total Time9.15s (± 0.48%)9.18s (± 0.42%)+0.03s (+ 0.34%)9.09s9.27s
material-ui - node (v12.1.0, x64)
Memory used439,707k (± 0.01%)439,686k (± 0.01%)-21k (- 0.00%)439,579k439,847k
Parse Time1.98s (± 0.53%)1.98s (± 0.33%)+0.00s (+ 0.00%)1.96s1.99s
Bind Time0.63s (± 0.91%)0.63s (± 0.91%)0.00s ( 0.00%)0.62s0.65s
Check Time12.17s (± 1.26%)11.95s (± 0.80%)-0.22s (- 1.79%)11.77s12.24s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time14.77s (± 1.06%)14.55s (± 0.67%)-0.22s (- 1.49%)14.37s14.84s
Angular - node (v8.9.0, x64)
Memory used341,102k (± 0.02%)341,057k (± 0.02%)-45k (- 0.01%)340,920k341,224k
Parse Time2.54s (± 0.58%)2.54s (± 0.55%)-0.00s (- 0.12%)2.51s2.57s
Bind Time0.85s (± 0.58%)0.86s (± 0.85%)+0.01s (+ 1.42%)0.84s0.87s
Check Time5.40s (± 0.48%)5.44s (± 0.43%)+0.04s (+ 0.72%)5.38s5.50s
Emit Time5.92s (± 0.49%)6.01s (± 1.40%)+0.08s (+ 1.42%)5.88s6.22s
Total Time14.72s (± 0.30%)14.85s (± 0.61%)+0.13s (+ 0.88%)14.71s15.13s
Monaco - node (v8.9.0, x64)
Memory used340,627k (± 0.01%)340,643k (± 0.01%)+16k (+ 0.00%)340,533k340,724k
Parse Time1.87s (± 0.41%)1.88s (± 0.44%)+0.01s (+ 0.27%)1.86s1.89s
Bind Time0.89s (± 0.56%)0.88s (± 0.63%)-0.00s (- 0.45%)0.87s0.90s
Check Time5.48s (± 0.53%)5.50s (± 0.49%)+0.02s (+ 0.35%)5.42s5.55s
Emit Time3.21s (± 0.58%)3.23s (± 0.92%)+0.01s (+ 0.40%)3.18s3.34s
Total Time11.45s (± 0.32%)11.49s (± 0.43%)+0.04s (+ 0.32%)11.39s11.65s
TFS - node (v8.9.0, x64)
Memory used303,971k (± 0.03%)303,940k (± 0.02%)-31k (- 0.01%)303,816k304,030k
Parse Time1.55s (± 0.57%)1.55s (± 0.38%)-0.00s (- 0.26%)1.53s1.56s
Bind Time0.68s (± 0.33%)0.68s (± 0.88%)-0.00s (- 0.44%)0.66s0.69s
Check Time5.22s (± 0.68%)5.22s (± 0.73%)0.00s ( 0.00%)5.15s5.31s
Emit Time2.92s (± 0.94%)2.94s (± 0.79%)+0.02s (+ 0.55%)2.86s2.98s
Total Time10.37s (± 0.42%)10.38s (± 0.51%)+0.01s (+ 0.12%)10.27s10.49s
material-ui - node (v8.9.0, x64)
Memory used465,698k (± 0.01%)465,640k (± 0.01%)-58k (- 0.01%)465,498k465,733k
Parse Time2.38s (± 0.47%)2.39s (± 0.64%)+0.01s (+ 0.42%)2.36s2.42s
Bind Time0.78s (± 1.65%)0.78s (± 1.20%)-0.00s (- 0.38%)0.76s0.80s
Check Time17.87s (± 1.28%)17.87s (± 0.81%)+0.00s (+ 0.01%)17.58s18.14s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time21.03s (± 1.08%)21.04s (± 0.65%)+0.01s (+ 0.04%)20.74s21.32s
Angular - node (v8.9.0, x86)
Memory used195,669k (± 0.02%)195,711k (± 0.01%)+42k (+ 0.02%)195,653k195,769k
Parse Time2.46s (± 0.72%)2.47s (± 0.60%)+0.01s (+ 0.45%)2.43s2.49s
Bind Time0.99s (± 0.60%)0.99s (± 0.77%)-0.00s (- 0.10%)0.97s1.00s
Check Time4.90s (± 0.44%)4.88s (± 0.75%)-0.01s (- 0.27%)4.81s4.95s
Emit Time5.91s (± 0.73%)5.94s (± 0.70%)+0.04s (+ 0.64%)5.85s6.07s
Total Time14.24s (± 0.28%)14.28s (± 0.43%)+0.03s (+ 0.23%)14.13s14.42s
Monaco - node (v8.9.0, x86)
Memory used193,655k (± 0.01%)193,689k (± 0.01%)+34k (+ 0.02%)193,607k193,742k
Parse Time1.90s (± 0.53%)1.91s (± 0.94%)+0.00s (+ 0.05%)1.88s1.95s
Bind Time0.70s (± 0.82%)0.70s (± 0.67%)-0.00s (- 0.00%)0.69s0.71s
Check Time5.60s (± 1.21%)5.61s (± 0.44%)+0.01s (+ 0.21%)5.56s5.66s
Emit Time2.71s (± 2.76%)2.65s (± 0.51%)-0.06s (- 2.28%)2.62s2.69s
Total Time10.92s (± 0.47%)10.87s (± 0.35%)-0.05s (- 0.46%)10.79s10.97s
TFS - node (v8.9.0, x86)
Memory used173,889k (± 0.04%)173,877k (± 0.02%)-13k (- 0.01%)173,824k173,935k
Parse Time1.59s (± 1.11%)1.58s (± 0.81%)-0.00s (- 0.25%)1.56s1.62s
Bind Time0.65s (± 1.72%)0.64s (± 0.46%)-0.00s (- 0.62%)0.64s0.65s
Check Time4.73s (± 0.66%)4.70s (± 0.37%)-0.03s (- 0.57%)4.67s4.74s
Emit Time2.80s (± 1.40%)2.79s (± 1.10%)-0.01s (- 0.29%)2.71s2.87s
Total Time9.76s (± 0.56%)9.72s (± 0.44%)-0.05s (- 0.47%)9.64s9.80s
material-ui - node (v8.9.0, x86)
Memory used263,677k (± 0.01%)263,694k (± 0.01%)+17k (+ 0.01%)263,616k263,765k
Parse Time2.44s (± 0.74%)2.44s (± 0.79%)-0.00s (- 0.12%)2.41s2.50s
Bind Time0.68s (± 1.92%)0.68s (± 0.85%)+0.00s (+ 0.15%)0.67s0.69s
Check Time16.59s (± 0.56%)16.29s (± 0.34%)-0.30s (- 1.78%)16.15s16.41s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time19.71s (± 0.50%)19.42s (± 0.30%)-0.30s (- 1.50%)19.26s19.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)
BenchmarkNameIterations
Current4031110
Baselinemaster10

@DanielRosenwasser

Daniel Rosenwasser (DanielRosenwasser) commented Aug 29, 2020

Copy link
Copy Markdown
MemberAuthor

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
Copy Markdown
MemberAuthor

@typescript-bot

TypeScript Bot (typescript-bot) commented Aug 29, 2020

Copy link
Copy Markdown
Contributor

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

@typescript-bot

TypeScript Bot (typescript-bot) commented Aug 29, 2020

Copy link
Copy Markdown
Contributor

Heya Daniel Rosenwasser (@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

TypeScript Bot (typescript-bot) commented Aug 29, 2020

Copy link
Copy Markdown
Contributor

Heya Daniel Rosenwasser (@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

TypeScript Bot (typescript-bot) commented Aug 29, 2020

Copy link
Copy Markdown
Contributor

Heya Daniel Rosenwasser (@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
Copy Markdown
Contributor

Hey Daniel Rosenwasser (@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

Daniel Rosenwasser (DanielRosenwasser) commented Aug 29, 2020

Copy link
Copy Markdown
MemberAuthor

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

interfaceObj{a: string;}declarefunctionfoo(obj: Obj): void;declarefunctionfoo(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
Copy Markdown
Contributor

Daniel Rosenwasser (@DanielRosenwasser)
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..40311

Metricmaster40311DeltaBestWorst
Angular - node (v10.16.3, x64)
Memory used344,479k (± 0.02%)344,619k (± 0.03%)+140k (+ 0.04%)344,444k344,774k
Parse Time2.00s (± 0.51%)1.99s (± 0.45%)-0.01s (- 0.35%)1.97s2.01s
Bind Time0.82s (± 0.70%)0.82s (± 1.52%)+0.00s (+ 0.49%)0.80s0.87s
Check Time4.76s (± 0.32%)4.80s (± 0.70%)+0.04s (+ 0.84%)4.75s4.90s
Emit Time5.17s (± 0.67%)5.17s (± 0.49%)+0.00s (+ 0.04%)5.12s5.22s
Total Time12.75s (± 0.39%)12.78s (± 0.27%)+0.04s (+ 0.28%)12.73s12.85s
Monaco - node (v10.16.3, x64)
Memory used339,354k (± 0.02%)339,394k (± 0.04%)+39k (+ 0.01%)339,215k339,756k
Parse Time1.54s (± 0.44%)1.55s (± 0.48%)+0.00s (+ 0.19%)1.53s1.56s
Bind Time0.71s (± 0.48%)0.71s (± 0.83%)+0.00s (+ 0.14%)0.70s0.73s
Check Time4.96s (± 0.73%)4.96s (± 0.67%)+0.00s (+ 0.00%)4.88s5.03s
Emit Time2.73s (± 0.33%)2.74s (± 0.53%)+0.01s (+ 0.26%)2.70s2.78s
Total Time9.95s (± 0.39%)9.96s (± 0.34%)+0.02s (+ 0.16%)9.90s10.05s
TFS - node (v10.16.3, x64)
Memory used302,328k (± 0.03%)302,356k (± 0.03%)+29k (+ 0.01%)302,043k302,519k
Parse Time1.20s (± 0.51%)1.21s (± 0.56%)+0.01s (+ 0.42%)1.19s1.22s
Bind Time0.66s (± 1.74%)0.67s (± 1.30%)+0.01s (+ 0.75%)0.65s0.69s
Check Time4.47s (± 0.58%)4.50s (± 0.59%)+0.03s (+ 0.69%)4.44s4.58s
Emit Time2.90s (± 1.04%)2.91s (± 1.21%)+0.01s (+ 0.17%)2.84s2.96s
Total Time9.24s (± 0.40%)9.28s (± 0.68%)+0.05s (+ 0.49%)9.18s9.42s
material-ui - node (v10.16.3, x64)
Memory used461,311k (± 0.01%)461,289k (± 0.01%)-23k (- 0.00%)461,163k461,426k
Parse Time1.95s (± 0.32%)1.95s (± 0.34%)+0.00s (+ 0.21%)1.94s1.97s
Bind Time0.65s (± 1.35%)0.66s (± 0.84%)+0.01s (+ 1.38%)0.65s0.67s
Check Time13.34s (± 0.37%)13.40s (± 0.73%)+0.06s (+ 0.43%)13.27s13.72s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time15.94s (± 0.34%)16.01s (± 0.62%)+0.07s (+ 0.43%)15.88s16.33s
Angular - node (v12.1.0, x64)
Memory used321,776k (± 0.03%)321,804k (± 0.03%)+28k (+ 0.01%)321,617k321,963k
Parse Time1.98s (± 0.69%)1.99s (± 0.54%)+0.00s (+ 0.25%)1.97s2.02s
Bind Time0.81s (± 0.69%)0.81s (± 0.80%)-0.00s (- 0.00%)0.80s0.82s
Check Time4.66s (± 0.48%)4.68s (± 0.54%)+0.03s (+ 0.56%)4.63s4.74s
Emit Time5.31s (± 0.53%)5.34s (± 0.67%)+0.03s (+ 0.62%)5.28s5.45s
Total Time12.75s (± 0.36%)12.82s (± 0.50%)+0.07s (+ 0.53%)12.68s13.00s
Monaco - node (v12.1.0, x64)
Memory used321,640k (± 0.02%)321,660k (± 0.02%)+20k (+ 0.01%)321,528k321,823k
Parse Time1.51s (± 0.54%)1.53s (± 0.80%)+0.02s (+ 1.19%)1.50s1.55s
Bind Time0.69s (± 0.81%)0.69s (± 0.32%)+0.00s (+ 0.44%)0.69s0.70s
Check Time4.74s (± 0.35%)4.77s (± 0.68%)+0.03s (+ 0.65%)4.73s4.85s
Emit Time2.78s (± 0.40%)2.81s (± 0.81%)+0.02s (+ 0.79%)2.77s2.88s
Total Time9.72s (± 0.23%)9.80s (± 0.42%)+0.08s (+ 0.77%)9.72s9.87s
TFS - node (v12.1.0, x64)
Memory used286,651k (± 0.04%)286,710k (± 0.02%)+60k (+ 0.02%)286,592k286,812k
Parse Time1.23s (± 0.76%)1.23s (± 0.50%)-0.00s (- 0.08%)1.22s1.25s
Bind Time0.64s (± 0.62%)0.64s (± 1.44%)+0.00s (+ 0.16%)0.62s0.66s
Check Time4.36s (± 0.41%)4.35s (± 0.46%)-0.01s (- 0.25%)4.29s4.38s
Emit Time2.92s (± 0.60%)2.91s (± 1.06%)-0.01s (- 0.27%)2.83s2.98s
Total Time9.14s (± 0.25%)9.13s (± 0.40%)-0.02s (- 0.19%)9.05s9.22s
material-ui - node (v12.1.0, x64)
Memory used439,532k (± 0.07%)439,563k (± 0.04%)+31k (+ 0.01%)438,786k439,744k
Parse Time1.98s (± 0.61%)1.97s (± 0.51%)-0.01s (- 0.25%)1.94s1.99s
Bind Time0.63s (± 1.03%)0.63s (± 0.75%)+0.00s (+ 0.32%)0.62s0.64s
Check Time11.96s (± 0.55%)12.03s (± 0.76%)+0.06s (+ 0.54%)11.86s12.25s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time14.57s (± 0.46%)14.63s (± 0.68%)+0.06s (+ 0.41%)14.44s14.86s
Angular - node (v8.9.0, x64)
Memory used341,064k (± 0.02%)341,125k (± 0.02%)+60k (+ 0.02%)341,006k341,244k
Parse Time2.54s (± 0.44%)2.54s (± 0.39%)-0.01s (- 0.28%)2.52s2.57s
Bind Time0.85s (± 0.61%)0.85s (± 0.55%)+0.00s (+ 0.12%)0.84s0.86s
Check Time5.41s (± 0.69%)5.43s (± 0.46%)+0.02s (+ 0.31%)5.38s5.50s
Emit Time5.93s (± 2.10%)5.93s (± 1.41%)-0.01s (- 0.10%)5.72s6.11s
Total Time14.74s (± 0.96%)14.75s (± 0.68%)+0.00s (+ 0.02%)14.55s15.00s
Monaco - node (v8.9.0, x64)
Memory used340,670k (± 0.02%)340,684k (± 0.01%)+14k (+ 0.00%)340,590k340,754k
Parse Time1.87s (± 0.28%)1.88s (± 0.37%)+0.01s (+ 0.43%)1.86s1.90s
Bind Time0.89s (± 0.54%)0.89s (± 0.42%)-0.00s (- 0.23%)0.88s0.89s
Check Time5.46s (± 0.68%)5.51s (± 0.45%)+0.05s (+ 0.88%)5.47s5.58s
Emit Time3.21s (± 0.96%)3.21s (± 0.57%)-0.00s (- 0.09%)3.18s3.27s
Total Time11.43s (± 0.48%)11.48s (± 0.33%)+0.05s (+ 0.42%)11.40s11.57s
TFS - node (v8.9.0, x64)
Memory used303,961k (± 0.01%)303,902k (± 0.02%)-59k (- 0.02%)303,820k304,031k
Parse Time1.55s (± 0.54%)1.54s (± 0.31%)-0.00s (- 0.13%)1.53s1.55s
Bind Time0.67s (± 0.66%)0.67s (± 1.04%)-0.00s (- 0.15%)0.66s0.69s
Check Time5.18s (± 0.56%)5.20s (± 0.54%)+0.02s (+ 0.39%)5.13s5.26s
Emit Time2.92s (± 0.87%)2.92s (± 0.87%)+0.00s (+ 0.07%)2.84s2.96s
Total Time10.32s (± 0.44%)10.34s (± 0.52%)+0.02s (+ 0.17%)10.17s10.45s
material-ui - node (v8.9.0, x64)
Memory used465,671k (± 0.01%)465,680k (± 0.01%)+10k (+ 0.00%)465,626k465,776k
Parse Time2.38s (± 0.40%)2.40s (± 0.81%)+0.02s (+ 0.84%)2.36s2.46s
Bind Time0.78s (± 1.28%)0.79s (± 0.82%)+0.00s (+ 0.51%)0.77s0.80s
Check Time18.00s (± 0.79%)17.93s (± 1.10%)-0.07s (- 0.39%)17.52s18.40s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time21.16s (± 0.69%)21.12s (± 0.91%)-0.05s (- 0.22%)20.71s21.57s
Angular - node (v8.9.0, x86)
Memory used195,721k (± 0.02%)195,677k (± 0.02%)-44k (- 0.02%)195,587k195,755k
Parse Time2.43s (± 0.30%)2.47s (± 0.70%)+0.03s (+ 1.40%)2.42s2.50s
Bind Time0.99s (± 0.59%)1.00s (± 0.60%)+0.01s (+ 0.91%)0.98s1.01s
Check Time4.88s (± 0.54%)4.88s (± 0.53%)+0.00s (+ 0.06%)4.84s4.94s
Emit Time5.97s (± 1.80%)5.96s (± 1.17%)-0.01s (- 0.23%)5.83s6.17s
Total Time14.27s (± 0.86%)14.30s (± 0.50%)+0.03s (+ 0.21%)14.13s14.47s
Monaco - node (v8.9.0, x86)
Memory used193,666k (± 0.01%)193,667k (± 0.03%)+1k (+ 0.00%)193,554k193,776k
Parse Time1.91s (± 1.24%)1.91s (± 0.79%)-0.00s (- 0.10%)1.88s1.95s
Bind Time0.70s (± 0.88%)0.70s (± 0.68%)-0.00s (- 0.29%)0.69s0.71s
Check Time5.59s (± 1.22%)5.58s (± 0.56%)-0.02s (- 0.32%)5.50s5.65s
Emit Time2.69s (± 2.98%)2.66s (± 1.06%)-0.03s (- 1.04%)2.62s2.74s
Total Time10.89s (± 0.46%)10.84s (± 0.32%)-0.06s (- 0.51%)10.77s10.92s
TFS - node (v8.9.0, x86)
Memory used173,892k (± 0.03%)173,876k (± 0.02%)-17k (- 0.01%)173,787k173,980k
Parse Time1.58s (± 0.65%)1.58s (± 0.60%)+0.00s (+ 0.19%)1.56s1.61s
Bind Time0.65s (± 1.38%)0.65s (± 1.63%)+0.00s (+ 0.15%)0.63s0.68s
Check Time4.68s (± 0.47%)4.72s (± 0.61%)+0.05s (+ 1.01%)4.67s4.80s
Emit Time2.77s (± 0.99%)2.80s (± 1.32%)+0.03s (+ 1.26%)2.75s2.92s
Total Time9.67s (± 0.31%)9.76s (± 0.47%)+0.09s (+ 0.90%)9.67s9.86s
material-ui - node (v8.9.0, x86)
Memory used263,649k (± 0.02%)263,681k (± 0.02%)+32k (+ 0.01%)263,596k263,751k
Parse Time2.43s (± 0.41%)2.45s (± 0.56%)+0.02s (+ 0.82%)2.42s2.48s
Bind Time0.67s (± 1.38%)0.68s (± 1.77%)+0.01s (+ 0.74%)0.66s0.71s
Check Time16.47s (± 0.68%)16.44s (± 0.91%)-0.03s (- 0.19%)16.25s16.80s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time19.58s (± 0.58%)19.57s (± 0.77%)-0.02s (- 0.08%)19.34s19.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)
BenchmarkNameIterations
Current4031110
Baselinemaster10

@DanielRosenwasserDaniel Rosenwasser (DanielRosenwasser) changed the title Don't widen inferred return types when a contextual type is availableDon't widen inferred return types when a contextual signature is availableAug 31, 2020
@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

TypeScript Bot (@typescript-bot) user test this

@typescript-bot

TypeScript Bot (typescript-bot) commented Aug 31, 2020

Copy link
Copy Markdown
Contributor

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

@DanielRosenwasserDaniel Rosenwasser (DanielRosenwasser) removed the Experiment A fork with an experimental idea which might not make it into master label Sep 2, 2020
@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

User test failures:

https://github.com/microsoft/fluentui/blob/bcf5ac28bfb4809a9097a8bec9bb26cba8d04ef6/packages/charting/src/components/VerticalStackedBarChart/examples/VerticalStackedBarChart.Styled.Example.tsx#L47-L49

src/components/VerticalStackedBarChart/examples/VerticalStackedBarChart.Styled.Example.tsx:47:9 - error TS2322: Type '() => { chart: { paddingBottom: string; }; chartLabel: { displayName?: string | undefined; selectors?: { [key: string]: IStyle; } | undefined; MsHighContrastAdjust?: string | undefined; MsOverflowStyle?: string | undefined; ... 277 more ...; fontWeight?: string | ... 9 more ... | undefined; }; xAxisText: { ...; }; }' is not assignable to type 'IStyleFunction<IVerticalStackedBarChartStyleProps, IVerticalStackedBarChartStyles> | DeepPartial<...> | undefined'.
@uifabric/charting: Type '() => { chart: { paddingBottom: string; }; chartLabel: { displayName?: string | undefined; selectors?: { [key: string]: IStyle; } | undefined; MsHighContrastAdjust?: string | undefined; MsOverflowStyle?: string | undefined; ... 277 more ...; fontWeight?: string | ... 9 more ... | undefined; }; xAxisText: { ...; }; }' is not assignable to type 'IStyleFunction<IVerticalStackedBarChartStyleProps, IVerticalStackedBarChartStyles>'.
@uifabric/charting: Type '{ chart: { paddingBottom: string; }; chartLabel: { displayName?: string | undefined; selectors?: { [key: string]: IStyle; } | undefined; MsHighContrastAdjust?: string | undefined; MsOverflowStyle?: string | undefined; ... 277 more ...; fontWeight?: string | ... 9 more ... | undefined; }; xAxisText: { ...; }; }' is not assignable to type 'DeepPartial<IVerticalStackedBarChartStyles>'.
@uifabric/charting: Object literal may only specify known properties, and 'chart' does not exist in type 'DeepPartial<IVerticalStackedBarChartStyles>'.

https://github.com/microsoft/fluentui/blob/bcf5ac28bfb4809a9097a8bec9bb26cba8d04ef6/packages/react-slider/src/next/Slider.tsx#L56

src/next/Slider.tsx:56:7 - error TS2322: Type '{ root: string; container: string; slideBox: string; line: string; thumb: string; activeSection: string; inactiveSection: string; lineContainer: string; valueLabel: string; titleLabel: string; showTransitions: string; zeroTick: string; }' is not assignable to type 'Required<ISliderStyles>'.
@fluentui/react-slider: Object literal may only specify known properties, and 'showTransitions' does not exist in type 'Required<ISliderStyles>'.
@fluentui/react-slider: 56 showTransitions: css(globalClassNames.showTransitions, ...propClasses),

https://github.com/microsoft/fluentui/blob/bcf5ac28bfb4809a9097a8bec9bb26cba8d04ef6/packages/date-time/src/components/Calendar/examples/Calendar.Inline.DateBoundaries.Example.tsx#L73

@uifabric/date-time: src/components/Calendar/examples/Calendar.Inline.DateBoundaries.Example.tsx:73:9 - error TS2345: Argument of type '(prevState: ICalendarInlineExampleState) => { selectedDate: Date; selectedDateRange: Date[]; }' is not assignable to parameter of type 'ICalendarInlineExampleState | ((prevState: Readonly<ICalendarInlineExampleState>, props: Readonly<{}>) => ICalendarInlineExampleState | ... 1 more ... | null) | Pick<...> | null'.
@uifabric/date-time: Type '(prevState: ICalendarInlineExampleState) => { selectedDate: Date; selectedDateRange: Date[]; }' is not assignable to type '(prevState: Readonly<ICalendarInlineExampleState>, props: Readonly<{}>) => ICalendarInlineExampleState | Pick<...> | null'.
@uifabric/date-time: Type '{ selectedDate: Date; selectedDateRange: Date[]; }' is not assignable to type 'ICalendarInlineExampleState | Pick<ICalendarInlineExampleState, "selectedDate"> | null'.
@uifabric/date-time: Object literal may only specify known properties, and 'selectedDateRange' does not exist in type 'ICalendarInlineExampleState | Pick<ICalendarInlineExampleState, "selectedDate">'.
@uifabric/date-time: 73 selectedDateRange: dateRangeArray,
@uifabric/date-time: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

David Zearing (@dzearing)Jason Gore (@JasonGore) we might break some of your code in 4.1, but I think these are mostly bugs. On the upside, this fixes #27237. 😄

@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

TypeScript Bot (@typescript-bot) pack this

@typescript-bot

TypeScript Bot (typescript-bot) commented Sep 4, 2020

Copy link
Copy Markdown
Contributor

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

@typescript-bot

TypeScript Bot (typescript-bot) commented Sep 4, 2020

Copy link
Copy Markdown
Contributor

Hey Daniel Rosenwasser (@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.

endLocation: Location;
category: string;
code: number;
source?: string;

Copy link
Copy Markdown
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
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
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
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown

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

@typescript-bot

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Member

Daniel Rosenwasser (@DanielRosenwasser) is this change still worth taking? If so, can you address Wesley Wigham (@weswigham)'s idea for named functions?

@mrlubos

Copy link
Copy Markdown

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

@sandersn

Copy link
Copy Markdown
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.

@thw0rted

Copy link
Copy Markdown

Daniel Rosenwasser (@DanielRosenwasser)Nathan Shively-Sanders (@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 Ryan Cavanaugh (@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
Copy Markdown
Member

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

@mogelbrod

Victor Hallberg (mogelbrod) commented Sep 16, 2021

Copy link
Copy Markdown

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
Copy Markdown

Daniel Rosenwasser (@DanielRosenwasser)Nathan Shively-Sanders (@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
Copy Markdown

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

@microsoftMicrosoft (microsoft) locked as resolved and limited conversation to collaborators Oct 16, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.