The comparison between importing and requiring mutable values for export

I'm exploring the distinction between import and require in relation to exporting and importing mutable values.

Picture a file a.ts:

export let a = 1;
export function f() {
  a = 2;
}

Next, we have three versions of a main file, index1.ts:

import { a, f } from "./a";

console.log(a); // 1
f();
console.log(a); // 2

index2.ts:

const { a, f } = require("./a");

console.log(a); // 1
f();
console.log(a); // 1

index3.ts:

const _ = require("./a");

console.log(_.a); // 1
_.f();
console.log(_.a); // 2
  • It was anticipated that index1.ts would yield the same result as index2.ts, however it does not. The imported a always points back to the actual a variable from a.ts. What assurances exist that this behavior will persist? Is this behavior mandated by the specifications?
  • index3.ts functions because the properties of the object returned by require are getters. Yet, can we always count on this being the case? Is it reliable for the construction of a library, for instance?

Answer №1

When using the `import` statement in JavaScript, imported identifiers can exhibit strange behavior. They may appear to reassign themselves if the exporting module reassigns what is being exported. This can lead to unexpected results, as demonstrated below:

import { a, f } from './a';
console.log(a);
f()
console.log(a);

In this scenario, the code could output 1 and then 2, a behavior that differs from typical JavaScript conventions.

Is this behavior mandated by the spec?

Yes, it is.

In contrast, using `require` instead of `import` returns a namespace object from the imported module. This object behaves more predictably, similar to other objects in JavaScript. If you destructure values from the object into variables, those values will not change unexpectedly unless explicitly reassigned.

Can we always rely on getters for the properties of the namespace object returned by `require`?

It is more about the properties of the namespace object getting reassigned when the exporting module reassigns them. For instance, if the exporting module contains the following:

// foo.ts
export let a = 1;
export function f() {
  a = 2;
}

The namespace object imported elsewhere will reflect the live values of the properties `a` and `f`. While it may be possible to leverage this behavior, it is advisable to avoid writing code that heavily relies on it due to its unconventional nature, which could lead to confusion for both developers and readers.

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

Exploring the directories: bundles, lib, lib-esm, and iife

As some libraries/frameworks prepare the application for publishing, they create a specific folder structure within the 'dist' directory including folders such as 'bundles', 'lib', 'lib-esm', and 'iife'. T ...

Troubleshooting issue: Unable to locate library during testing with Nx, Jest, and Angular

In my nx monorepo, I have two apps (client, server) and 5 libraries (client-core, platform-core, etc). To include the libraries in the Angular client application, I set the paths in the tsconfig.json file. "paths": { "@myorg/platfo ...

Clicking on a component in Nuxt will trigger it to open

Is there a way to trigger a modal window to open when a button is clicked without storing the modal window in the header? file header: <template> <section class="header"> <div class="header-container"> ...

JavaScript for Office Spreadsheet Titles

I'm having trouble fetching the names of sheets from an external Excel file, as I keep getting an empty array. async function retrieveSheetNames() { const fileInput = <HTMLInputElement>document.getElementById("file"); const fileReader ...

Looking to update the state of a nested object with useReducer?

I am currently developing a Next.js application using Typescript and I need to make changes to a nested object state. Here is the structure of the state: const initialState ={ userInfo: string | null, isLoading: boolean, cursorState: boolean, compa ...

In Typescript ReactJS, how can the useReducer hook be implemented to increment a particular property of an object upon clicking a button?

Is there a better way to increase the property values of an Attribute object (STR, AGI, INT, and CHA) using useReducer actions? I currently have separate actions for each property, but it leads to a lot of redundant code. I'm looking for a more effici ...

Alert: User is currently engaging in typing activity, utilizing a streamlined RXJS approach

In my current project, I am in the process of adding a feature that shows when a user is typing in a multi-user chat room. Despite my limited understanding of RXJS, I managed to come up with the code snippet below which satisfies the basic requirements for ...

Having trouble connecting my chosen color from the color picker

Currently, I am working on an angularJS typescript application where I am trying to retrieve a color from a color picker. While I am successfully obtaining the value from the color picker, I am facing difficulty in binding this color as a background to my ...

Discovering the most efficient route between two locations within a grid of values

I'm currently working on a game where I need to find the shortest route between two points. https://i.sstatic.net/jBnEd.png In my map, I have a 2D array called matrix: Node[][], class Node{ index: { x: number, y: number }, isAvai ...

Disregarding TypeScript import errors within a monorepo ecosystem

In my Turborepo monorepo, I have a Next.js app package that imports various components from a shared package. This shared package is not compiled; it simply contains components imported directly by apps in the monorepo. The issue arises with the shared co ...

Implementing Microdata with React and Typescript: A Comprehensive Guide

Whenever I include itemscope itemtype="http://schema.org/Product" in h1, an error pops up: The type '{ children: string; itemscope: true; itemtype: string; }' is not compatible with the type 'DetailedHTMLProps<HTMLAttributes<HTMLH ...

Having trouble retrieving data in Angular from the TypeScript file

demo.component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-demo', templateUrl: './demo.component.html', styleUrls: ['./demo.component.css'] }) ...

Building a customized Mui clip with child support: A step-by-step guide

Looking to create a customized chip that can handle both single and nested declarations? Check out this example using MUI v5. interface StyledModalChipProps { theme: Theme children: React.ReactNode } export const StyledModalChip = styled(Chip)<Styled ...

Angular's capability for manipulating data asynchronously

I am relatively new to this, and I am facing difficulties in handling data manipulation in the frontend of an app that I'm currently developing. In my code, there are two functions named "getTipoEtapas()" and "getEtapasporTransfo" which utilize two s ...

Mastering the art of managing promises within nested loops

Embarking on my Promise journey, I find myself faced with a scenario where a list of objects within another list of objects needs to be updated based on responses from an external API. I've attempted to simulate the scenario below. The code snippet f ...

At first, Typescript generics make an inference but are ultimately specified

In my TypeScript code, I have defined a custom Logger class with specific options. The DefaultLevel type is created as a union of 'info' and 'error'. The LoggerOptions interface includes two generics, CustomLevels and Level, where Custo ...

Error: JSON encountered circular structure when attempting to serialize an object of type 'ClientRequest' with a property 'socket' that references an object of type 'Socket'

Encountering an error while attempting to make a POST request to my TypeORM API using axios: TypeError: Converting circular structure to JSON --> starting at object with constructor 'ClientRequest' | property 'socket' -&g ...

How can I update a value using a specific key in Angular?

So, I have a string value that I need to pass to another function. For instance, if the string is 'eng', I want it to be converted to 'en'. I'm looking for a solution that does not involve using slice or if statements. I attempted ...

typescript dispatch issue

Whenever I attempt to send this dispatch, it consistently results in the following error message (and the same issue occurs with all my other dispatches): The argument of type '(dispatch: Dispatch) => Promise' is not compatible with a paramet ...

Is there a method to define an 'internal' property within a TypeScript type?

I created a custom 'library' in Angular and TypeScript. This library is distributed as a *.ts package within other Angular workspaces. Within this library, I have an exported class that contains various properties. One specific property in thi ...