Is there a possibility of Typescript expressions `A` existing where the concept of truthiness is not the same as when applying `!!A`?

When working with JavaScript, it is important to note that almost all expressions have a "truthiness" value. This means that if you use an expression in a statement that expects a boolean, it will be evaluated as a boolean equivalent. For example:

let a = 'foo'

if (a) {
  console.log('a is truthy!');
}
// Output: 'a is truthy!'.

Some workplaces have a common practice of coercing an expression into an actual boolean by negating it twice in this situation:

let a = 'foo'

if (!!a) {
  console.log('a is truthy!');
}
// Output: 'a is truthy!'.

The question arises: Is this double negation merely a matter of style? Does it serve solely to communicate to other developers that we are aware a is not a boolean but intend to evaluate it as such anyway? Or are there situations where the boolean value produced by if (a) differs from if (!!a)?

Answer №1

The factuality of a and !!a will consistently remain unchanged.

ToBoolean is a fixed lookup process that does not trigger any custom code execution at any stage. Using ! initiates ToBoolean, followed by negating the outcome. Likewise, if also employs ToBoolean, interpreting the result without extensive alterations. Given that double negation acts as an identity element, and ToBoolean doesn't modify anything if the input is already boolean, their values will always align.

In short, in pseudocode, "ToBoolean(a) === ToBoolean(booleanNot(ToBoolean(booleanNot(ToBoolean(a)))))".


It's important to note that altering the variable during each query might lead to perplexing tests, but they do not invalidate the aforementioned logic. The value of a changes after the initial evaluation - whether using !! or not makes no impact:

let x = 0;
let objectEnvironment = { get a() { return x++; } };
with(objectEnvironment){
  if (a) console.log("truthy?");
  if (!!a) console.log("double negated truthy?");
}

If you interchange the utilization of a and !!a in the above example, the output remains unaffected. Keep in mind that with is considered erroneous in strict mode and should be avoided. This demonstration merely illustrates how GetValue can execute user-defined code. Nonetheless, it is impossible to distinguish whether logical not was employed or not, making it ineffective to create conditions based on this distinction.

Answer №2

Is this simply a matter of style? Is it just to convey to someone reading the code that we acknowledge that a is not a boolean, but still plan to evaluate it as such?

For more information, check out Why use if (!!err)?

Are there any circumstances where expressions or values of a could cause if (a) to give a different boolean result than if (!!a)?

No, unless 'a' consistently refers to something different each time (like a getter with random output). Refer to the specification:

Logical NOT Operator (!)

  1. Evaluate UnaryExpression to get expr.
  2. Determine ToBoolean(? GetValue(expr)) as oldValue.
  3. If oldValue is true, return false.
  4. Return true.

The if statement

  1. Evaluate Expression to get exprRef.
  2. Determine ToBoolean(? GetValue(exprRef)) as exprValue.
  3. If exprValue is true, then
    • Evaluate the first Statement as stmtCompletion.
  4. Else,
    • Evaluate the second Statement as stmtCompletion.
  5. Return Completion(UpdateEmpty(stmtCompletion, undefined)).

Both the logical NOT operator and the if statement utilize the ToBoolean function. So, in essence, there shouldn't be a difference between using if (a) versus if (!!a) (provided both 'a's point to the same reference).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

performing resolver when needed in angular version 5

I have been working on a project using Angular and recently updated it from version 4.2 to Angular 5. Although I haven't utilized any new features introduced in Angular 5 yet. My current task involves executing a resolver on a specific route when a c ...

Ways to show the existing value of a <select> in a label without altering the function

I currently have a label that changes to display the selected option from a dynamic select dropdown, but it only updates when the selection is changed. I would like it to also display the current value when the page first loads. I attempted to change &apos ...

What is the best way to verify that a JSON key contains only distinct values within a JSON document using JavaScript?

I'm working with a JSON file structure that looks something like this: "fields": { "asset": { "values": [{ "asset": { "id": "Info_text", "type": "text", "value": "ABCD" } ...

Convert an array of objects into an object where the keys are determined by the value of a specific

I'm working with an array that looks like this: const inventory = [ { fruit: 'apple', quality: 'good', quantity: 10 }, { fruit: 'banana', quality: 'average', quantity: 5 }, { fruit: 'orange', qua ...

Share the constructor and enumeration in an npm module for exportation

My background in NPM and Node.js is limited, as my expertise lies mainly in JavaScript for web browsers. Recently, I created a JavaScript library that consists of a constructor function and an enum type. In JavaScript, enums do not exist natively, so the ...

Access the file and execute JavaScript code concurrently

Can I simultaneously link to a file as noticias.php and call a JavaScript function? <a href="javascript:toggleDiv('novidades');" class="linktriangulo"></a> The toggleDiv function in my noticias.php file: function toggleDiv(divId) { ...

Issue with Three.js CanvasRenderer not displaying Mesh when using multiple materials

Encountering an issue with CanvasRenderer not rendering a Mesh that has multiple materials applied to a BoxBufferGeometry. The Mesh appears without any materials when using CanvasRenderer, but works as expected with WebGLRenderer. Check out the example co ...

v-autocomplete no selected option

Within my Vue.js 2 and Vuetify component, I am receiving the following data : [ { "anio": 2022, "__typename": "Grupo" }, { "anio": 2020, "__typename": "Grupo" }, { "anio": 2018, "__ ...

Getting the Class name in Typescript

How can you retrieve the class name from within a Class in typescript? For instance, consider this code snippet: export class SomeRandomName extends AbstractSomething<SomeType> implements OnDestroy { className = 'SomeRandomName'; Is th ...

Draggable slider not functioning properly with linear interpolation

Recently, I've been delving into the world of "linear interpolation" and its application in creating easing effects. However, while the easing functionality of the draggable slider seems to be operational, I'm encountering an issue. The slider re ...

Display the user's input value in a tooltip without using jQuery

I am looking to achieve this particular layout design. https://i.stack.imgur.com/p9UTH.jpg I am unsure about how to display the input value in the bubble within this layout. The visibility of the bubble should only be triggered on hover. Below is the cod ...

Failed to execute start script 'ng serve' in npm start

Let me make it clear: I'm brand new to AngularJS and pretty much any Web Technology. I consider myself a novice in the realm of Web Development. I attempted to install AngularJS, and truth be told, after numerous "Mysterious Button Clicks", I might ...

The Ajax Process continues to run even after the user has navigated away from the page

Currently, I have a JavaScript function that refreshes a specific section of a Rails-generated view every 2.5 seconds using a JS request to update a basic progress bar. function refreshPage(){ $.ajax({ type:"GET", dataType:"script" }) } s ...

What is the best way to create a select box in React that allows for both single and multiple selections?

I recently started utilizing a new package for generating dynamic forms, which can be found at this link. Upon reading through the documentation, I attempted to create a select box as outlined in the instructions provided here. Despite following the step ...

Combine several JSON files into a single file

After spending countless hours searching on Google, I finally gathered the courage to ask my question here. I have several json files. localhost/feed01.json localhost/feed02.json localhost/feed03.json All of the json file structures are similar to this ...

Storing Documents on Your Device

I've been working on a project to create a web page that provides links to online PDF files. When you click on these links, the file should be saved locally and its name/path added to local storage. I then aim to display all the saved files by iterati ...

What causes the "Method Not Allowed" error while trying to restore the package.json package in VS2015?

When trying to restore a package.json file in VS2015, I am encountering a "Method Not Allowed" error. https://i.stack.imgur.com/OgK5P.png https://i.stack.imgur.com/AAkoQ.png The error log displays the following: npm ERR! Error: Method Not Allowed npm ER ...

How can I inform Typescript that an interface will exclusively consist of defined members?

My interface looks like this interface Person { name?:string; age? :number; gender?:string } I need to reuse the same interface type, but with a modification indicating that all members will never be undefined. The updated version would look like this: ...

Having trouble retrieving the component state within AgGrid's cellRenderer

When working on my React app using functional components, I encountered an issue with accessing a local state (myObj) within a cellRenderer in AgGrid. The local state is populated via a context object from the parent component based on an API response. Un ...

Solution to bypass JavaScript PHP login system

Creating a login/register system with JavaScript to display specific divs for the system: 1st div = menu option to either log in or register 2nd div = shows login form or register form depending on what was clicked (login or register) 3rd div = displays ...