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.

prefer-const incorrect gives an error on exported variables that are changed in a different file

See original GitHub issue

Tell us about your environment

Node version: v10.15.3 npm version: v6.4.1 Local ESLint version: v6.8.0 Global ESLint version: v7.2.0 (Currently used)

What parser (default, @babel/eslint-parser, @typescript-eslint/parser, etc.) are you using? @typescript-eslint/parser

Please show your full configuration:

Configuration

https://github.com/microsoft/vscode-cpptools/blob/master/Extension/.eslintrc.js

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

file1.ts

export let test: boolean = false;

file2.ts

import mod = require('./file1');
mod.test = true;

gulp lint

What did you expect to happen? No error 'test' is never reassigned. Use 'const' instead.. The code won’t compile with ‘const’ because it complains in file2 that it is changing a read-only variable.

What actually happened? Please include the actual, raw output from ESLint. error 'test' is never reassigned. Use 'const' instead..

See https://dev.azure.com/ms/vscode-cpptools/_build/results?buildId=104586&view=logs&j=2d2b3007-3c5c-5840-9bb0-2b1ea49925f3&t=3f67303d-caa6-535b-2055-750b67f1a4bf

Are you willing to submit a pull request to fix this bug? No.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
bradzachercommented, Aug 27, 2020

It is a TS compiler error to attempt to assign to an imported variable.

given:

// ./bar.ts
export let mylet = 1;

TS will (correctly) hard error if you attempt to reassign the variable

import { mylet } from './bar';
mylet = 1;
// Cannot assign to 'mylet' because it is not a variable. ts(2539)
import * as mod from './bar';
mod.mylet = 1;
// Cannot assign to 'mylet' because it is a read-only property.ts(2540)

however if you use an import assignment, then it allows it, because TS is conceding that you’re doing javascripty things with commonjs modules:

import mod = require('./bar');
mod.mylet = 1; // no error

However this is a large antipattern. You should not do this. The fact that your code transpiles to commonjs under the hood is an implementation detail that shouldn’t be relied upon. If you rely upon it, when the underlying system changes to ES6 modules your code will be irrevocably broken.

Instead if you must use this pattern of mutating constants from a module, consider exporting an object:

// ./bar.ts
export const obj = { mylet: 1 };

// ./foo.ts
import { obj } from './bar';
obj.mylet = 1; // no error
1reaction
mdjermanoviccommented, Aug 26, 2020

Hi @sean-mcmanus, thanks for the issue!

I think it’s correct behavior for the core prefer-const rule.

Per the specification for ES modules, the exported test cannot be reassigned from another module:

import * as mod from './file1';

mod.test = true; // this would throw
import { test } from './file1';

test = true; // this would also throw

Given that, the rule doesn’t account for the fact that the variable is export-ed, because it isn’t allowed to assign to that variable in other modules, regardless of the variable’s kind (let or const).

The use case you presented relies on ts compiler specifics, where export let test actually becomes exports.test, so it is possible to change its value in runtime. However, supporting this build-specific behavior is out of scope for this rule.

Maybe ESLint Plugin TypeScript could provide a replacement rule to support this use case (i.e., not warn on export let).

Read more comments on GitHub >

github_iconTop Results From Across the Web

prefer-const incorrect gives an error on exported variables that ...
The code won't compile with 'const' because it complains in file2 that it is changing a read-only variable. Actual Result. error 'test' is ......
Read more >
prefer-const - ESLint - Pluggable JavaScript Linter
A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.
Read more >
javascript - module.export not changing variable for other file?
A contrived example of exporting functions that manage data housed in the singleton module, rather than the data itself.
Read more >
Linter rules - Dart programming language
Tip: Linter rules (sometimes called lints) can have false positives, ... Error rules. These rules identify possible errors and other mistakes in your...
Read more >
rollup.js
Rollup provides a JavaScript API which is usable from Node.js. ... ES modules export live bindings, not values, so values can be changed...
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