Skip to content

Commit e60cf12

Browse files
authored
Add check for reference-compared literals to JS files (#49164)
1 parent 6a996ac commit e60cf12

File tree

7 files changed

+69
-1
lines changed

7 files changed

+69
-1
lines changed

src/compiler/checker.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -37024,7 +37024,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3702437024
// control flow analysis it is possible for operands to temporarily have narrower types, and those narrower
3702537025
// types may cause the operands to not be comparable. We don't want such errors reported (see #46475).
3702637026
if (!(checkMode && checkMode & CheckMode.TypeOnly)) {
37027-
if (isLiteralExpressionOfObject(left) || isLiteralExpressionOfObject(right)) {
37027+
if (
37028+
(isLiteralExpressionOfObject(left) || isLiteralExpressionOfObject(right)) &&
37029+
// only report for === and !== in JS, not == or !=
37030+
(!isInJSFile(left) || (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken))
37031+
) {
3702837032
const eqType = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken;
3702937033
error(errorNode, Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value, eqType ? "false" : "true");
3703037034
}

src/compiler/program.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,8 @@ export const plainJSErrors: Set<number> = new Set([
14301430
Diagnostics.Class_constructor_may_not_be_a_generator.code,
14311431
Diagnostics.Class_constructor_may_not_be_an_accessor.code,
14321432
Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
1433+
// Type errors
1434+
Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value.code,
14331435
]);
14341436

14351437
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
plainJSTypeErrors.js(2,5): error TS2839: This condition will always return 'false' since JavaScript compares objects by reference, not value.
2+
3+
4+
==== plainJSTypeErrors.js (1 errors) ====
5+
// should error
6+
if ({} === {}) {}
7+
~~~~~~~~~
8+
!!! error TS2839: This condition will always return 'false' since JavaScript compares objects by reference, not value.
9+
10+
// should not error
11+
if ({} == {}) {}
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/conformance/salsa/plainJSTypeErrors.ts] ////
2+
3+
//// [plainJSTypeErrors.js]
4+
// should error
5+
if ({} === {}) {}
6+
7+
// should not error
8+
if ({} == {}) {}
9+
10+
11+
//// [plainJSTypeErrors.js]
12+
// should error
13+
if ({} === {}) { }
14+
// should not error
15+
if ({} == {}) { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [tests/cases/conformance/salsa/plainJSTypeErrors.ts] ////
2+
3+
=== plainJSTypeErrors.js ===
4+
5+
// should error
6+
if ({} === {}) {}
7+
8+
// should not error
9+
if ({} == {}) {}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/conformance/salsa/plainJSTypeErrors.ts] ////
2+
3+
=== plainJSTypeErrors.js ===
4+
// should error
5+
if ({} === {}) {}
6+
>{} === {} : boolean
7+
>{} : {}
8+
>{} : {}
9+
10+
// should not error
11+
if ({} == {}) {}
12+
>{} == {} : boolean
13+
>{} : {}
14+
>{} : {}
15+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @outdir: out/
2+
// @target: esnext
3+
// @allowJS: true
4+
// @filename: plainJSTypeErrors.js
5+
6+
// should error
7+
if ({} === {}) {}
8+
9+
// should not error
10+
if ({} == {}) {}

0 commit comments

Comments
 (0)