Uh oh!
There was an error while loading. Please reload this page.
Unify logic in typeof narrowing - #33434
Conversation
Jack Williams (jack-williams)
commented
Sep 14, 2019
TypeScript Bot (@typescript-bot) test this because bots don't get weekends. |
Heya Jack Williams (@jack-williams), I've started to run the extended test suite on this PR at 8be155d. You can monitor the build here. It should now contribute to this PR's status checks. |
Heya Jack Williams (@jack-williams), I've started to run the perf test suite on this PR at 8be155d. You can monitor the build here. It should now contribute to this PR's status checks. Update: The results are in! |
Heya Jack Williams (@jack-williams), I've started to run the parallelized community code test suite on this PR at 8be155d. You can monitor the build here. It should now contribute to this PR's status checks. |
TypeScript Bot (typescript-bot)
commented
Sep 14, 2019
Jack Williams (@jack-williams) Here they are:Comparison Report - master..33434
System
Hosts
Scenarios
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TypeScript Bot (typescript-bot)
commented
Sep 14, 2019
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
Jack Williams (jack-williams)
commented
Sep 14, 2019
User tests look like noise, I think. |
8be155d to
17ed7e2Compare
While this narrowing does match the reality at runtime, I'm not sure it's sound semantically, given that IMO, any construct that allows a value of type declareletcallback: ()=>void=()=>true;declareletknownToBeBool;declarefunctionfoo(b: boolean): void;letx=Math.random()>0.5 ? callback() : knownToBeBool;if(typeofx==='boolean'){// 'x' should NOT be narrowed here because it could leak the return value of 'callback'// (which we've already promised to ignore by declaring it 'void')foo(x);} |
The Care needs to be taken with empty intersection reduction of void, which I’m not sure is entirely correct right now, but the principle of narrowing void in general does not seem unsound - at least in relation to the typical understanding of soundness. |
Bruce Pascoe (fatcerberus)
commented
Sep 15, 2019
Quibbles about theoretical details aside (suffice to say there's no practical reason to disallow |
In other words: declarefunctiondoSomething(callback: ()=>void);doSomething(someRandoFunction);Since |
Bruce Pascoe (fatcerberus)
commented
Sep 15, 2019
Not related to this issue, but this just got me thinking, how much real-world code would break if this were actually the case... because if that change were made, Function types returning |
The
|
Jack Williams (jack-williams)
commented
Sep 15, 2019
If the proposed behaviour does not introduce significant real-world breaks I think it could be justified, though I don't know the landscape well enough. The behaviour feels slightly draconian though, given that even unconstrained type parameters can be inspected and narrowed. The priority should be addressing the unsound behaviour that narrows In modern TypeScript with |
IMO Put another way, We can think of |
Bruce Pascoe (fatcerberus)
commented
Sep 15, 2019
To cut through the noise and be clear (and get back on-topic): I only mean to argue that narrowing |
Jack Williams (jack-williams)
commented
Sep 15, 2019
If this really is a desirable and bug-reducing feature I think the correct thing is to introduce non-narrowable type parameters and use generics.
There may be similarities when interpreting the contract of Narrowing The former is clearly unsound under any reasonably definition and should be fixed. The latter is open to interpretation. |
The way I see Therefore, Obviously, yes, if I’ll see if I can come up with a practical example later, so we’re not dealing entirely with intangible theory. If so I’ll also open a separate issue for discussion and stop spamming this one. 😄 |
Ethan Resnick (ethanresnick)
commented
Oct 9, 2019
Possibly relevant: #32809 |
Jack Williams (jack-williams)
commented
Mar 13, 2020
I'll get to merging this in the next week (for anyone planning to review this). |
Wesley Wigham (weswigham)
left a comment
There was a problem hiding this comment.
The diff is a little hard to read because of the reordering, but this just looks like a relatively small refactoring. It does need a merge though.
Jack Williams (jack-williams)
commented
Mar 30, 2020
Will do! |
Nathan Shively-Sanders (sandersn)
commented
May 6, 2020
Jack Williams (@jack-williams)Wesley Wigham (@weswigham) should we close this now? I wasn't sure from the discussion whether it's completely obsoleted by #38311 but it sounds like it. |
Nathan Shively-Sanders (@sandersn) The only objective here is to unify the logic of #38311 changes the root type for discriminant narrowing, so I think it solves a different problem. I did have another PR which was correctly replaced. I've merged master and moved things around to reduce the diff, hopefully this makes it clearer. Feel free to close or merge, whatever you see fit. I think we should get this out of the open PR's either way! Tests fail because of n/n-1 with linter in master. |
913cd6d to
76e9b26Compare
In looking to resolve#33180 I want something like
if (typeof x === "boolean") { ... }to narrowxtobooleanwhenxis of typeboolean | void, such behaviour is consistent with empty intersection reduction.Doing so requires changing both
ifandswitchlogic. It also feels more robust moving forward to unify the logic inif (typeof x === "boolean") { ... }andswitch (typeof x) { ... }, so I'm looking to merge this first and then fix thevoidcase---hoping to avoid conflating any regressions.