From 141eb5900ad8028f4284ec2cb1ce8d0334d80185 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 29 Oct 2024 22:09:19 +0200 Subject: [PATCH 1/5] don't report on the 'missing' undefined type if it's covered with an undefined type --- .../src/rules/switch-exhaustiveness-check.ts | 9 +++ .../rules/switch-exhaustiveness-check.test.ts | 55 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 62fbfcbd3c6f..27e8deff7556 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -155,6 +155,15 @@ export default createRule({ continue; } + // `undefined` should cover the "missing" undefined type + // https://github.com/microsoft/TypeScript/blob/cb44488fcec4348a448434afbf2ebcbf2b423c61/src/compiler/checker.ts/#L2059 + if ( + caseTypes.has(checker.getUndefinedType()) && + tsutils.isIntrinsicUndefinedType(intersectionPart) + ) { + continue; + } + missingLiteralBranchTypes.push(intersectionPart); } } diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index a3e9dd90cdd0..0490d8c4163e 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -912,6 +912,24 @@ switch (value) { }, ], }, + { + code: ` +function foo(x: string[]) { + switch (x[0]) { + case 'hi': + break; + case undefined: + break; + } +} + `, + languageOptions: { + parserOptions: { + project: './tsconfig.noUncheckedIndexedAccess.json', + tsconfigRootDir: rootPath, + }, + }, + }, ], invalid: [ { @@ -2717,5 +2735,42 @@ switch (value) { }, ], }, + { + code: ` +function foo(x: string[]) { + switch (x[0]) { + case 'hi': + break; + } +} + `, + errors: [ + { + column: 11, + line: 3, + messageId: 'switchIsNotExhaustive', + suggestions: [ + { + messageId: 'addMissingCases', + output: ` +function foo(x: string[]) { + switch (x[0]) { + case 'hi': + break; + case undefined: { throw new Error('Not implemented yet: undefined case') } + } +} + `, + }, + ], + }, + ], + languageOptions: { + parserOptions: { + project: './tsconfig.noUncheckedIndexedAccess.json', + tsconfigRootDir: rootPath, + }, + }, + }, ], }); From f7ab3c4726fb7babbbdd491697335b1032c01115 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 29 Oct 2024 22:56:43 +0200 Subject: [PATCH 2/5] projectService: false --- .../tests/rules/switch-exhaustiveness-check.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index 0490d8c4163e..40db39465380 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -2768,6 +2768,7 @@ function foo(x: string[]) { languageOptions: { parserOptions: { project: './tsconfig.noUncheckedIndexedAccess.json', + projectService: false, tsconfigRootDir: rootPath, }, }, From e52e44cab17e921aaee417640770046ad21aaa55 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 29 Oct 2024 22:58:08 +0200 Subject: [PATCH 3/5] projectService: false on valid test too --- .../tests/rules/switch-exhaustiveness-check.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index 40db39465380..8efe52223363 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -926,6 +926,7 @@ function foo(x: string[]) { languageOptions: { parserOptions: { project: './tsconfig.noUncheckedIndexedAccess.json', + projectService: false, tsconfigRootDir: rootPath, }, }, From 674c1589d17fbd98055f1a8765d7093f087202ae Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Wed, 30 Oct 2024 18:57:51 +0200 Subject: [PATCH 4/5] Update packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> --- .../eslint-plugin/src/rules/switch-exhaustiveness-check.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 27e8deff7556..8dd9c0f26b27 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -155,10 +155,10 @@ export default createRule({ continue; } - // `undefined` should cover the "missing" undefined type - // https://github.com/microsoft/TypeScript/blob/cb44488fcec4348a448434afbf2ebcbf2b423c61/src/compiler/checker.ts/#L2059 + // "missing", "optional" and "undefined" types are different runtime objects, + // but all of them have TypeFlags.Undefined type flag if ( - caseTypes.has(checker.getUndefinedType()) && + Array.from(caseTypes).some(tsutils.isIntrinsicUndefinedType) && tsutils.isIntrinsicUndefinedType(intersectionPart) ) { continue; From 64a712c01cb6eb5cba809a9a8422b91692aad85d Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Wed, 30 Oct 2024 19:01:10 +0200 Subject: [PATCH 5/5] add relevant test --- .../src/rules/switch-exhaustiveness-check.ts | 2 +- .../rules/switch-exhaustiveness-check.test.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 8dd9c0f26b27..4b5b178068cd 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -158,7 +158,7 @@ export default createRule({ // "missing", "optional" and "undefined" types are different runtime objects, // but all of them have TypeFlags.Undefined type flag if ( - Array.from(caseTypes).some(tsutils.isIntrinsicUndefinedType) && + [...caseTypes].some(tsutils.isIntrinsicUndefinedType) && tsutils.isIntrinsicUndefinedType(intersectionPart) ) { continue; diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index 8efe52223363..c7b9b62e9ea4 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -921,6 +921,29 @@ function foo(x: string[]) { case undefined: break; } +} + `, + languageOptions: { + parserOptions: { + project: './tsconfig.noUncheckedIndexedAccess.json', + projectService: false, + tsconfigRootDir: rootPath, + }, + }, + }, + { + code: ` +function foo(x: string[], y: string | undefined) { + const a = x[0]; + if (typeof a === 'string') { + return; + } + switch (y) { + case 'hi': + break; + case a: + break; + } } `, languageOptions: { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy