Skip to content

Add flag to change catch variables' default types to unknown - #41013

Merged
DanielRosenwasser merged 9 commits into
mainfrom
unknownInCatchVariables
Jun 3, 2021
Merged

Add flag to change catch variables' default types to unknown#41013
DanielRosenwasser merged 9 commits into
mainfrom
unknownInCatchVariables

Conversation

@DanielRosenwasser

@DanielRosenwasserDanielRosenwasser commented Oct 9, 2020

Copy link
Copy Markdown
Member

This change adds a new flag called useUnknownInCatchVariables which changes the default type of catch clause variables from any (today's existing behavior) to unknown.

More specifically, under this flag, the following code

try{// ...}catch(err){console.log(err.message);}

would become equivalent to

try{// ...}catch(err: unknown){console.log(err.message);// error: Property 'message' does not exist on type 'unknown'.}

As a result, a user would receive the following error message from TypeScript:

Property 'message' does not exist on type 'unknown'.

To mitigate this, a user could explicitly perform runtime checks

try{// ...}catch(err){// First check if we have an Errorif(errinstanceofError){console.log(err.message);}}

or if that is too painful, a user could use a type assertion to any, or provide an explicit annotation on the catch clause variable with the type any to revert to the old default behavior.

try{// ...}catch(err: any){console.log(err.message);}

Fixes#41016.

@typescript-bottypescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Oct 9, 2020
@DanielRosenwasserDanielRosenwasser changed the title 'unknown' in catch variables--useUnknownInCatchVariablesOct 9, 2020
@DanielRosenwasserDanielRosenwasser changed the title --useUnknownInCatchVariablesAdd flag to change 'catch' variable default to 'unknown'Oct 9, 2020
@DanielRosenwasser
DanielRosenwasser marked this pull request as ready for review October 9, 2020 21:10
@sandersnsandersn added the Experiment A fork with an experimental idea which might not make it into master label Oct 20, 2020
@typescript-bot

Copy link
Copy Markdown
Contributor

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

@johnnyreilly

johnnyreilly commented Feb 10, 2021

Copy link
Copy Markdown

It would be awesome if strict also enabled this flag; is that likely? (It's possible that this change does that already; but I'm on my phone so it's hard to tell 😅)

@DanielRosenwasser
DanielRosenwasserforce-pushed the unknownInCatchVariables branch from 7c01840 to f529457CompareMay 5, 2021 21:36
@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

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

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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

Update: The results are in!

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented May 5, 2021

Copy link
Copy Markdown
Contributor

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/102337/artifacts?artifactName=tgz&fileId=CB39C963580F3F2B857D3171C4A6770212DE0222B86B618B209B2F4B2E12A36B02&fileName=/typescript-4.3.0-insiders.20210505.tgz"
}
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@4.3.0-pr-41013-8".;

@typescript-bot

Copy link
Copy Markdown
Contributor

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

Here they are:

Comparison Report - master..41013

Metricmaster41013DeltaBestWorst
Angular - node (v10.16.3, x64)
Memory used344,651k (± 0.02%)344,706k (± 0.03%)+54k (+ 0.02%)344,444k344,928k
Parse Time1.91s (± 0.55%)1.90s (± 0.43%)-0.01s (- 0.52%)1.89s1.92s
Bind Time0.84s (± 0.57%)0.84s (± 0.57%)0.00s ( 0.00%)0.83s0.85s
Check Time5.25s (± 0.47%)5.25s (± 0.31%)+0.00s (+ 0.06%)5.23s5.29s
Emit Time5.89s (± 0.38%)5.91s (± 1.20%)+0.02s (+ 0.36%)5.80s6.16s
Total Time13.89s (± 0.29%)13.91s (± 0.58%)+0.02s (+ 0.12%)13.78s14.15s
Compiler-Unions - node (v10.16.3, x64)
Memory used200,759k (± 0.03%)200,821k (± 0.03%)+62k (+ 0.03%)200,671k200,923k
Parse Time0.79s (± 0.51%)0.78s (± 0.97%)-0.01s (- 0.63%)0.77s0.80s
Bind Time0.53s (± 1.27%)0.52s (± 0.91%)-0.00s (- 0.76%)0.51s0.53s
Check Time7.59s (± 0.57%)7.59s (± 0.65%)-0.00s (- 0.05%)7.47s7.72s
Emit Time2.51s (± 1.43%)2.48s (± 0.90%)-0.03s (- 1.12%)2.43s2.52s
Total Time11.42s (± 0.47%)11.38s (± 0.53%)-0.04s (- 0.36%)11.24s11.56s
Monaco - node (v10.16.3, x64)
Memory used341,715k (± 0.01%)341,688k (± 0.02%)-27k (- 0.01%)341,565k341,920k
Parse Time1.56s (± 0.50%)1.57s (± 0.61%)+0.01s (+ 0.38%)1.54s1.59s
Bind Time0.74s (± 0.78%)0.74s (± 0.98%)-0.00s (- 0.13%)0.73s0.76s
Check Time5.38s (± 0.34%)5.38s (± 0.52%)-0.00s (- 0.02%)5.31s5.45s
Emit Time3.02s (± 0.86%)3.01s (± 0.75%)-0.01s (- 0.20%)2.97s3.06s
Total Time10.70s (± 0.39%)10.70s (± 0.45%)-0.00s (- 0.05%)10.59s10.80s
TFS - node (v10.16.3, x64)
Memory used304,178k (± 0.03%)304,226k (± 0.02%)+48k (+ 0.02%)304,099k304,366k
Parse Time1.22s (± 0.55%)1.21s (± 0.48%)-0.00s (- 0.33%)1.20s1.23s
Bind Time0.71s (± 0.78%)0.71s (± 1.03%)-0.00s (- 0.56%)0.69s0.72s
Check Time4.79s (± 0.42%)4.80s (± 0.47%)+0.01s (+ 0.23%)4.73s4.84s
Emit Time3.21s (± 1.33%)3.18s (± 1.60%)-0.03s (- 1.00%)3.03s3.27s
Total Time9.93s (± 0.53%)9.90s (± 0.66%)-0.02s (- 0.24%)9.76s10.03s
material-ui - node (v10.16.3, x64)
Memory used474,572k (± 0.02%)474,591k (± 0.01%)+19k (+ 0.00%)474,488k474,712k
Parse Time1.94s (± 0.79%)1.94s (± 0.41%)-0.00s (- 0.10%)1.92s1.96s
Bind Time0.65s (± 1.23%)0.65s (± 0.80%)-0.00s (- 0.15%)0.64s0.66s
Check Time14.81s (± 0.66%)14.76s (± 0.64%)-0.06s (- 0.39%)14.63s15.10s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time17.41s (± 0.63%)17.35s (± 0.54%)-0.06s (- 0.35%)17.24s17.70s
Angular - node (v12.1.0, x64)
Memory used322,324k (± 0.02%)322,310k (± 0.02%)-14k (- 0.00%)322,163k322,427k
Parse Time1.91s (± 0.63%)1.91s (± 0.66%)-0.00s (- 0.05%)1.88s1.94s
Bind Time0.82s (± 0.73%)0.82s (± 0.70%)-0.00s (- 0.61%)0.81s0.84s
Check Time5.17s (± 0.48%)5.14s (± 0.42%)-0.03s (- 0.52%)5.11s5.21s
Emit Time6.16s (± 0.82%)6.15s (± 0.87%)-0.02s (- 0.24%)6.06s6.27s
Total Time14.07s (± 0.49%)14.02s (± 0.46%)-0.05s (- 0.35%)13.91s14.21s
Compiler-Unions - node (v12.1.0, x64)
Memory used187,812k (± 0.14%)188,033k (± 0.15%)+221k (+ 0.12%)187,234k188,396k
Parse Time0.77s (± 0.62%)0.77s (± 0.84%)-0.01s (- 0.65%)0.76s0.78s
Bind Time0.53s (± 0.89%)0.53s (± 0.98%)-0.00s (- 0.19%)0.52s0.54s
Check Time7.04s (± 0.64%)7.02s (± 0.42%)-0.02s (- 0.30%)6.98s7.10s
Emit Time2.49s (± 1.00%)2.47s (± 1.28%)-0.02s (- 1.00%)2.43s2.57s
Total Time10.84s (± 0.63%)10.79s (± 0.32%)-0.05s (- 0.49%)10.69s10.85s
Monaco - node (v12.1.0, x64)
Memory used324,057k (± 0.02%)324,057k (± 0.01%)+0k (+ 0.00%)323,992k324,106k
Parse Time1.54s (± 0.71%)1.54s (± 0.87%)+0.00s (+ 0.19%)1.52s1.58s
Bind Time0.72s (± 1.20%)0.72s (± 0.62%)-0.00s (- 0.55%)0.71s0.73s
Check Time5.20s (± 0.29%)5.21s (± 0.63%)+0.01s (+ 0.23%)5.13s5.28s
Emit Time3.06s (± 0.70%)3.06s (± 1.26%)-0.00s (- 0.03%)3.02s3.21s
Total Time10.52s (± 0.33%)10.54s (± 0.60%)+0.01s (+ 0.12%)10.41s10.72s
TFS - node (v12.1.0, x64)
Memory used288,711k (± 0.01%)288,704k (± 0.01%)-7k (- 0.00%)288,622k288,776k
Parse Time1.21s (± 0.78%)1.21s (± 0.43%)-0.00s (- 0.16%)1.20s1.22s
Bind Time0.70s (± 1.16%)0.69s (± 0.86%)-0.01s (- 1.14%)0.68s0.71s
Check Time4.70s (± 0.61%)4.70s (± 0.45%)-0.00s (- 0.04%)4.66s4.75s
Emit Time3.18s (± 1.55%)3.17s (± 0.46%)-0.01s (- 0.35%)3.14s3.21s
Total Time9.80s (± 0.64%)9.78s (± 0.24%)-0.02s (- 0.22%)9.73s9.83s
material-ui - node (v12.1.0, x64)
Memory used452,433k (± 0.05%)452,478k (± 0.01%)+45k (+ 0.01%)452,351k452,672k
Parse Time1.94s (± 0.38%)1.95s (± 0.37%)+0.01s (+ 0.52%)1.93s1.96s
Bind Time0.64s (± 0.63%)0.64s (± 1.17%)-0.00s (- 0.31%)0.63s0.66s
Check Time13.30s (± 0.52%)13.26s (± 0.40%)-0.04s (- 0.32%)13.15s13.41s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time15.88s (± 0.43%)15.84s (± 0.36%)-0.04s (- 0.23%)15.73s15.99s
Angular - node (v14.15.1, x64)
Memory used321,052k (± 0.01%)321,051k (± 0.00%)-2k (- 0.00%)321,024k321,066k
Parse Time1.90s (± 0.66%)1.90s (± 0.53%)+0.00s (+ 0.11%)1.89s1.93s
Bind Time0.87s (± 0.66%)0.87s (± 0.51%)+0.00s (+ 0.23%)0.86s0.88s
Check Time5.15s (± 0.44%)5.16s (± 0.46%)+0.00s (+ 0.08%)5.08s5.20s
Emit Time6.19s (± 0.64%)6.22s (± 0.75%)+0.03s (+ 0.52%)6.10s6.33s
Total Time14.11s (± 0.28%)14.15s (± 0.45%)+0.04s (+ 0.29%)14.02s14.31s
Compiler-Unions - node (v14.15.1, x64)
Memory used188,505k (± 0.64%)188,815k (± 0.62%)+310k (+ 0.16%)186,850k190,136k
Parse Time0.80s (± 0.59%)0.80s (± 0.56%)+0.00s (+ 0.25%)0.79s0.81s
Bind Time0.55s (± 0.62%)0.55s (± 0.62%)0.00s ( 0.00%)0.55s0.56s
Check Time7.13s (± 0.47%)7.16s (± 0.72%)+0.03s (+ 0.36%)7.09s7.29s
Emit Time2.49s (± 0.83%)2.48s (± 0.63%)-0.01s (- 0.44%)2.45s2.52s
Total Time10.98s (± 0.36%)10.99s (± 0.49%)+0.01s (+ 0.11%)10.92s11.14s
Monaco - node (v14.15.1, x64)
Memory used323,144k (± 0.01%)323,129k (± 0.01%)-15k (- 0.00%)323,075k323,158k
Parse Time1.57s (± 0.70%)1.57s (± 0.64%)+0.01s (+ 0.38%)1.55s1.60s
Bind Time0.75s (± 0.77%)0.75s (± 0.60%)-0.00s (- 0.27%)0.74s0.76s
Check Time5.19s (± 0.30%)5.17s (± 0.45%)-0.01s (- 0.19%)5.14s5.24s
Emit Time3.13s (± 0.67%)3.11s (± 0.68%)-0.02s (- 0.61%)3.08s3.17s
Total Time10.63s (± 0.23%)10.61s (± 0.38%)-0.02s (- 0.23%)10.54s10.74s
TFS - node (v14.15.1, x64)
Memory used287,663k (± 0.01%)287,670k (± 0.01%)+7k (+ 0.00%)287,626k287,720k
Parse Time1.27s (± 1.48%)1.27s (± 1.21%)-0.00s (- 0.08%)1.23s1.30s
Bind Time0.72s (± 1.17%)0.72s (± 0.81%)-0.00s (- 0.55%)0.71s0.73s
Check Time4.70s (± 0.38%)4.73s (± 0.45%)+0.03s (+ 0.55%)4.67s4.77s
Emit Time3.26s (± 0.40%)3.29s (± 0.83%)+0.03s (+ 0.80%)3.23s3.38s
Total Time9.95s (± 0.27%)10.00s (± 0.47%)+0.05s (+ 0.48%)9.92s10.11s
material-ui - node (v14.15.1, x64)
Memory used450,697k (± 0.00%)450,711k (± 0.01%)+14k (+ 0.00%)450,646k450,831k
Parse Time2.00s (± 0.62%)1.98s (± 1.10%)-0.02s (- 0.80%)1.93s2.03s
Bind Time0.70s (± 0.74%)0.70s (± 0.85%)-0.00s (- 0.43%)0.69s0.71s
Check Time13.61s (± 0.91%)13.41s (± 0.66%)-0.20s (- 1.48%)13.16s13.55s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time16.31s (± 0.76%)16.09s (± 0.65%)-0.22s (- 1.32%)15.78s16.28s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-206-generic
Architecturex64
Available Memory16 GB
Available Memory7 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v14.15.1, x64)
BenchmarkNameIterations
Current4101310
Baselinemaster10

Developer Information:

Download Benchmark

@DanielRosenwasserDanielRosenwasser removed the Experiment A fork with an experimental idea which might not make it into master label May 5, 2021
@typescript-bottypescript-bot added the For Milestone Bug PRs that fix a bug with a specific milestone label May 14, 2021

@sandersnsandersn left a comment

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.

commandLineParser entry should make the new flag a strict one, I think.

Comment threadsrc/compiler/commandLineParser.ts Outdated
@@ -0,0 +1,35 @@
// @useUnknownInCatchVariables: true

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.

except for this, I'm not convinced we even need a new test, since we know that unknown narrows, and from some other tests, that strict changes the type of the catch variable to unknown.

I guess there's nothing to change here, except possibly dropping the narrowing tests from this test.

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.

I added that style of code in because most of the purpose of this feature is to ensure that catch variables are narrowed, and that we error on usages if a user doesn't do so.

@gvanrossum

Copy link
Copy Markdown

Meta: I was confused by the initial comment, because I wasn't familiar with unknown. I'd say that the first snippet, with catch (err) should not have a comment indicating the error (because IIUC without the new flag it doesn't produce an error), and the second snippet, with explicit catch (err: unknown)should have the error comment, because even without the new flag that's an error. (Right?)

@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

@gvanrossum good call, thanks! Must have been an earlier copy/paste error.

@sandersnsandersn left a comment

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.

👍🏼 Does what we talked about in the design meeting.

Side note: It's a little worrying that we don't already have more tests with both (1) catch and (2) strict: true.

@DanielRosenwasser
DanielRosenwasser merged commit 9906092 into mainJun 3, 2021
@DanielRosenwasser
DanielRosenwasser deleted the unknownInCatchVariables branch June 3, 2021 20:13
@DanielRosenwasserDanielRosenwasser added the Breaking Change Would introduce errors in existing code label Jun 3, 2021
rekmarks added a commit to MetaMask/eslint-config that referenced this pull request Aug 30, 2021
Fixes the `no-throw-literal` rule configuration for TypeScript by enabling the appropriate rule in the TypeScript config, per [documentation](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-throw-literal.md#how-to-use).
This is timely due to recent [changes to TypeScript](microsoft/TypeScript#41013).
nightah added a commit to authelia/authelia that referenced this pull request Sep 2, 2021
Typescript 4.x changes the default behaviour of try catch and its err type from `any` to [`unknown`](microsoft/TypeScript#41013).
This change ensures that where we rely on said variable it is cast accordingly as an `Error`.
nightah added a commit to authelia/authelia that referenced this pull request Sep 4, 2021
* build(deps): update dependency typescript to v4.4.2
* fix(web): cast try catch err type to error
Typescript 4.x changes the default behaviour of try catch and its err type from `any` to [`unknown`](microsoft/TypeScript#41013).
This change ensures that where we rely on said variable it is cast accordingly as an `Error`.
Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Amir Zarrinkafsh <nightah@me.com>
@pvinis

Copy link
Copy Markdown

Is there a way to type a function that it throws specific types? So that catch could know what to expect.

Like a func that can throw MyError, and then catch knows that e is MyError.

@DanielRosenwasser

Copy link
Copy Markdown
MemberAuthor

Should the flag useUnknownInCatchVariables also affect the return type of Promise.prototype.catch?

@guilhermesimoes#45602 proposes that idea.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Breaking ChangeWould introduce errors in existing codeFor Milestone BugPRs that fix a bug with a specific milestone

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Flag to type 'catch' variables as 'unknown'.

7 participants

@DanielRosenwasser@typescript-bot@johnnyreilly@gvanrossum@pvinis@guilhermesimoes@sandersn