mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Ignore switch statement bypass control flows that produce never (#51703)
* Ignore switch statement bypass control flows that produce 'never' * Add regression test
This commit is contained in:
parent
d43112a75b
commit
b9d0e17298
@ -26073,7 +26073,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// If the bypass flow contributes a type we haven't seen yet and the switch statement
|
||||
// isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase
|
||||
// the risk of circularities, we only want to perform them when they make a difference.
|
||||
if (!contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
|
||||
if (!(type.flags & TypeFlags.Never) && !contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
|
||||
if (type === declaredType && declaredType === initialType) {
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -22,4 +22,22 @@ tests/cases/compiler/exhaustiveSwitchCheckCircularity.ts(14,26): error TS2345: A
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #51688
|
||||
|
||||
declare function functionB(key: string): string;
|
||||
|
||||
function functionC(): void {
|
||||
let unionVal: "A" | "B" = "A";
|
||||
while (true) {
|
||||
let key: string;
|
||||
switch (unionVal) {
|
||||
case "A": {
|
||||
key = "AA";
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,24 @@ function f() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #51688
|
||||
|
||||
declare function functionB(key: string): string;
|
||||
|
||||
function functionC(): void {
|
||||
let unionVal: "A" | "B" = "A";
|
||||
while (true) {
|
||||
let key: string;
|
||||
switch (unionVal) {
|
||||
case "A": {
|
||||
key = "AA";
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [exhaustiveSwitchCheckCircularity.js]
|
||||
@ -36,3 +54,16 @@ function f() {
|
||||
}
|
||||
}
|
||||
}
|
||||
function functionC() {
|
||||
var unionVal = "A";
|
||||
while (true) {
|
||||
var key = void 0;
|
||||
switch (unionVal) {
|
||||
case "A": {
|
||||
key = "AA";
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,3 +32,35 @@ function f() {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #51688
|
||||
|
||||
declare function functionB(key: string): string;
|
||||
>functionB : Symbol(functionB, Decl(exhaustiveSwitchCheckCircularity.ts, 17, 1))
|
||||
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 21, 27))
|
||||
|
||||
function functionC(): void {
|
||||
>functionC : Symbol(functionC, Decl(exhaustiveSwitchCheckCircularity.ts, 21, 48))
|
||||
|
||||
let unionVal: "A" | "B" = "A";
|
||||
>unionVal : Symbol(unionVal, Decl(exhaustiveSwitchCheckCircularity.ts, 24, 7))
|
||||
|
||||
while (true) {
|
||||
let key: string;
|
||||
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
|
||||
|
||||
switch (unionVal) {
|
||||
>unionVal : Symbol(unionVal, Decl(exhaustiveSwitchCheckCircularity.ts, 24, 7))
|
||||
|
||||
case "A": {
|
||||
key = "AA";
|
||||
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
>functionB : Symbol(functionB, Decl(exhaustiveSwitchCheckCircularity.ts, 17, 1))
|
||||
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,3 +41,43 @@ function f() {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #51688
|
||||
|
||||
declare function functionB(key: string): string;
|
||||
>functionB : (key: string) => string
|
||||
>key : string
|
||||
|
||||
function functionC(): void {
|
||||
>functionC : () => void
|
||||
|
||||
let unionVal: "A" | "B" = "A";
|
||||
>unionVal : "A" | "B"
|
||||
>"A" : "A"
|
||||
|
||||
while (true) {
|
||||
>true : true
|
||||
|
||||
let key: string;
|
||||
>key : string
|
||||
|
||||
switch (unionVal) {
|
||||
>unionVal : "A"
|
||||
|
||||
case "A": {
|
||||
>"A" : "A"
|
||||
|
||||
key = "AA";
|
||||
>key = "AA" : "AA"
|
||||
>key : string
|
||||
>"AA" : "AA"
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
>functionB(key) : string
|
||||
>functionB : (key: string) => string
|
||||
>key : string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,3 +18,21 @@ function f() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #51688
|
||||
|
||||
declare function functionB(key: string): string;
|
||||
|
||||
function functionC(): void {
|
||||
let unionVal: "A" | "B" = "A";
|
||||
while (true) {
|
||||
let key: string;
|
||||
switch (unionVal) {
|
||||
case "A": {
|
||||
key = "AA";
|
||||
break;
|
||||
}
|
||||
}
|
||||
functionB(key);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user