question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

Type of `([].length > 1 && {})` can be false but Typescript cannot detect it

See original GitHub issue

Bug 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:open
  • Created a year ago
  • Comments:15 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
RyanCavanaughcommented, Oct 10, 2022

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.

1reaction
omidh14commented, Oct 11, 2022

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

const x = { ...'a string which works fine in vanilla JS' } // Spread types may only be created from object types 
Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found