Type of `([].length > 1 && {})` can be false but Typescript cannot detect it
See original GitHub issueBug Report
š Search Terms
object type condition parenthesis
š Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ.
āÆ Playground Link
Playground link with relevant code
š» Code
// This throws an error as expected because "Spread types may only be created from object types"
const invalid = { ...(false) }
// This does not throw even though the value in parenthesis would also be resolved to `false` which
// is a side effect of wrong type detection. This assignment is allowed because Typescript cannot detect
// that there is a possibility that the value inside the parenthesis would be `false`.
const valid = { ...([].length > 1 && {}) }
const wrongTypeDetection = ([].length > 1 && {}) // type of wrongTypeDetection is {} instead of false | {}
š Actual behavior
Type of const wrongTypeDetection = ([].length > 1 && {})
is {}
š Expected behavior
Type of const wrongTypeDetection = ([].length > 1 && {})
should be false | {}
Issue Analytics
- State:
- Created a year ago
- Comments:15 (5 by maintainers)
Top Results From Across the Web
This condition will always return 'false' since the types '0' ...
Empty tuples always have a length of 0 , and since length can't be any other number, the type of length is the...
Read more >TSConfig Reference - Docs on every TSConfig option
When strictNullChecks is true , null and undefined have their own distinct types and you'll get a type error if you try to...
Read more >The 10 Most Common JavaScript Issues Developers Face
JavaScript Issue #1: Incorrect References to this ... As these examples demonstrate, the rules of type coercion can sometimes be clear as mud....
Read more >Comparing Arrays in JavaScript ā How to Compare 2 ...
But unfortunately, you cannot use them in this case. ... ways you can compare two arrays in JavaScript to see if they are...
Read more >Node.js v19.3.0 Documentation
See assert.throws() for more details. The following, for instance, will throw the TypeError because there is no matching error type in the assertionĀ ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Letās say your partner sends you to the store with a shopping list. They say āGet me the things on this list if they have them, but donāt get anything not on the listā. You look at the list and the item is just ātotatoā. What should you do?
You could go to the store and come back with nothing. That seems like a bad move, since surely something was intended here, and the store never stocks totatos. You could say āDid you mean potato, or tomato?ā before leaving. That seems like the right move.
Next week, you go to the store, and they send a carrier pigeon with the shopping list to meet you there (the cell network is down). The list again says ātotatoā. You come back with nothing, since youāre not supposed to buy anything not on the list. Did you mess up?
One theory of the situation is that you were wrong to reject the initial list. The instructions were explicit: you should have gone to the store, checked for totatos, and came back with nothing. Errors are not your problem, even if they render the instructions 100% nonsensical.
In another theory of the situation, you shouldnāt have agreed to go to the store at all the second time, since you plainly reject some shopping lists and were given no proof that the carrier pigeon would carry a valid list. Your partner might bristle at this - carrier pigeons are very effective at delivering shopping lists, and supplying an up-front proof that the list will not contain problematic items is very difficult.
The third theory is that itās okay to reject some shopping lists with upfront errors, while still accepting future lists even though they canāt be checked ahead of time, even though this is not consistent. In fact, this is probably the behavior thatās most desired ā identifying detectable early errors is valuable, and accepting late-bound data is valuable, and consistency between the two behaviors is a distant third in terms of importance in being a useful grocery-getter.
By claiming to accept any grocery list you might get in the future, but rejecting some lists you can read right away, youāve created a āholeā in the logic of your behavior, since any invalid list can be āmade validā by sending it via pigeon, which is illogical - yet still useful. Itās a subtyping symmetry violation. These are usually problematic, but not always ā sometimes if you know more about a situation, you can provide better feedback than if you know less about a situation. Thatās not a problem! Inconsistency in the face of different situations is not inconsistency, itās application of data.
TypeScript has the same view ā that there are operations which are facially problematic in the presence of statically-determinable facts (object-spreading a value like
true
, for example, which doesnāt do anything), but also operations which might end up doing the same thing (object-spreading {}) which should be presumed OK, because they have safe and reasonable no-op behavior.@RyanCavanaugh Thank you for the explanation but thatās an overly complicated example that raises more questions than answering them.
But before that, can you also explain why is this invalid in Typescript?