Why is this an issue?

Assigning a value to an import variable will cause a runtime error and will raise a compilation error in TypeScript.

Named imports

When using named imports, the imported identifier is a live binding exported by another module. Live bindings can be updated or reassigned by the exporting module, and the imported value would also change. The importing module cannot reassign it.

import { exportedObject } from 'module.js';
exportedObject = 'hello world!';   // Noncompliant: TypeError: Assignment to constant variable.

This rule will not raise an issue when a module mutates the imported object. Be aware that all other modules importing the same value will observe the mutated value.

import { exportedObject } from 'module.js';
exportedObject.newAttribute = 'hello world!'; // exportedObject now contains newAttribute and can be seen from all other modules importing it

Namespace and dynamic imports

This rule will raise an issue when modifying members of a module namespace object. A module namespace object is a sealed object that describes all exports from a module.

This can be done using

import * as module from 'module.js';
module.newObject = module.exportedObject; // Noncompliant: TypeError: Cannot add property readPath, object is not extensible
import('module.js').then(module => {
  module.newObject = module.exportedObject; // Noncompliant: TypeError: Cannot add property readPath, object is not extensible
})

Default imports

Default imports are live bindings to the default export. As with the other forms of import declarations, the importing module cannot reassign it.

import module from 'module.js';
module = 'hello world!';   // Noncompliant: TypeError: Assignment to constant variable.

However, the object which default refers to is not a live binding and may still be mutated by importing modules.

import moduleDefault from 'module.js';
moduleDefault.newAttribute = 'hello world!'; // module.default now contains newAttribute and can be seen from all other modules importing it

Resources