mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #5639 from Microsoft/typecheckStatementsInCaseClause
always check statements in case clause
This commit is contained in:
@@ -12886,13 +12886,13 @@ namespace ts {
|
||||
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
|
||||
const caseType = checkExpression(caseClause.expression);
|
||||
|
||||
// Permit 'number[] | "foo"' to be asserted to 'string'.
|
||||
if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) {
|
||||
return;
|
||||
}
|
||||
const expressionTypeIsAssignableToCaseType =
|
||||
// Permit 'number[] | "foo"' to be asserted to 'string'.
|
||||
(expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) ||
|
||||
isTypeAssignableTo(expressionType, caseType);
|
||||
|
||||
if (!isTypeAssignableTo(expressionType, caseType)) {
|
||||
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
|
||||
if (!expressionTypeIsAssignableToCaseType) {
|
||||
// 'expressionType is not assignable to caseType', try the reversed check and report errors if it fails
|
||||
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//// [checkSwitchStatementIfCaseTypeIsString.ts]
|
||||
declare function use(a: any): void;
|
||||
|
||||
class A {
|
||||
doIt(x: Array<string>): void {
|
||||
x.forEach((v) => {
|
||||
switch(v) {
|
||||
case "test": use(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//// [checkSwitchStatementIfCaseTypeIsString.js]
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.doIt = function (x) {
|
||||
var _this = this;
|
||||
x.forEach(function (v) {
|
||||
switch (v) {
|
||||
case "test": use(_this);
|
||||
}
|
||||
});
|
||||
};
|
||||
return A;
|
||||
})();
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/compiler/checkSwitchStatementIfCaseTypeIsString.ts ===
|
||||
declare function use(a: any): void;
|
||||
>use : Symbol(use, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 0, 21))
|
||||
|
||||
class A {
|
||||
>A : Symbol(A, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 0, 35))
|
||||
|
||||
doIt(x: Array<string>): void {
|
||||
>doIt : Symbol(doIt, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 2, 9))
|
||||
>x : Symbol(x, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 3, 9))
|
||||
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
x.forEach((v) => {
|
||||
>x.forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 3, 9))
|
||||
>forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --))
|
||||
>v : Symbol(v, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 4, 19))
|
||||
|
||||
switch(v) {
|
||||
>v : Symbol(v, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 4, 19))
|
||||
|
||||
case "test": use(this);
|
||||
>use : Symbol(use, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 0, 0))
|
||||
>this : Symbol(A, Decl(checkSwitchStatementIfCaseTypeIsString.ts, 0, 35))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/checkSwitchStatementIfCaseTypeIsString.ts ===
|
||||
declare function use(a: any): void;
|
||||
>use : (a: any) => void
|
||||
>a : any
|
||||
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
doIt(x: Array<string>): void {
|
||||
>doIt : (x: string[]) => void
|
||||
>x : string[]
|
||||
>Array : T[]
|
||||
|
||||
x.forEach((v) => {
|
||||
>x.forEach((v) => { switch(v) { case "test": use(this); } }) : void
|
||||
>x.forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void
|
||||
>x : string[]
|
||||
>forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void
|
||||
>(v) => { switch(v) { case "test": use(this); } } : (v: string) => void
|
||||
>v : string
|
||||
|
||||
switch(v) {
|
||||
>v : string
|
||||
|
||||
case "test": use(this);
|
||||
>"test" : string
|
||||
>use(this) : void
|
||||
>use : (a: any) => void
|
||||
>this : this
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
declare function use(a: any): void;
|
||||
|
||||
class A {
|
||||
doIt(x: Array<string>): void {
|
||||
x.forEach((v) => {
|
||||
switch(v) {
|
||||
case "test": use(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user