mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 12:32:08 -06:00
Fixed type narrowing in switch statements with parenthesized expressions (#56035)
This commit is contained in:
parent
61a96b1641
commit
9144836360
@ -27446,7 +27446,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType {
|
||||
const expr = flow.switchStatement.expression;
|
||||
const expr = skipParentheses(flow.switchStatement.expression);
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
let type = getTypeFromFlowType(flowType);
|
||||
if (isMatchingReference(reference, expr)) {
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
//// [tests/cases/compiler/narrowByParenthesizedSwitchExpression.ts] ////
|
||||
|
||||
=== narrowByParenthesizedSwitchExpression.ts ===
|
||||
interface Base {
|
||||
>Base : Symbol(Base, Decl(narrowByParenthesizedSwitchExpression.ts, 0, 0))
|
||||
|
||||
type: "foo" | "bar";
|
||||
>type : Symbol(Base.type, Decl(narrowByParenthesizedSwitchExpression.ts, 0, 16))
|
||||
}
|
||||
|
||||
interface Foo extends Base {
|
||||
>Foo : Symbol(Foo, Decl(narrowByParenthesizedSwitchExpression.ts, 2, 1))
|
||||
>Base : Symbol(Base, Decl(narrowByParenthesizedSwitchExpression.ts, 0, 0))
|
||||
|
||||
type: "foo";
|
||||
>type : Symbol(Foo.type, Decl(narrowByParenthesizedSwitchExpression.ts, 4, 28))
|
||||
|
||||
foo: string;
|
||||
>foo : Symbol(Foo.foo, Decl(narrowByParenthesizedSwitchExpression.ts, 5, 14))
|
||||
}
|
||||
|
||||
interface Bar extends Base {
|
||||
>Bar : Symbol(Bar, Decl(narrowByParenthesizedSwitchExpression.ts, 7, 1))
|
||||
>Base : Symbol(Base, Decl(narrowByParenthesizedSwitchExpression.ts, 0, 0))
|
||||
|
||||
type: "bar";
|
||||
>type : Symbol(Bar.type, Decl(narrowByParenthesizedSwitchExpression.ts, 9, 28))
|
||||
|
||||
bar: number;
|
||||
>bar : Symbol(Bar.bar, Decl(narrowByParenthesizedSwitchExpression.ts, 10, 14))
|
||||
}
|
||||
|
||||
function getV(): Foo | Bar {
|
||||
>getV : Symbol(getV, Decl(narrowByParenthesizedSwitchExpression.ts, 12, 1))
|
||||
>Foo : Symbol(Foo, Decl(narrowByParenthesizedSwitchExpression.ts, 2, 1))
|
||||
>Bar : Symbol(Bar, Decl(narrowByParenthesizedSwitchExpression.ts, 7, 1))
|
||||
|
||||
return null!;
|
||||
}
|
||||
|
||||
const v = getV();
|
||||
>v : Symbol(v, Decl(narrowByParenthesizedSwitchExpression.ts, 18, 5))
|
||||
>getV : Symbol(getV, Decl(narrowByParenthesizedSwitchExpression.ts, 12, 1))
|
||||
|
||||
switch ((v.type)) {
|
||||
>v.type : Symbol(type, Decl(narrowByParenthesizedSwitchExpression.ts, 4, 28), Decl(narrowByParenthesizedSwitchExpression.ts, 9, 28))
|
||||
>v : Symbol(v, Decl(narrowByParenthesizedSwitchExpression.ts, 18, 5))
|
||||
>type : Symbol(type, Decl(narrowByParenthesizedSwitchExpression.ts, 4, 28), Decl(narrowByParenthesizedSwitchExpression.ts, 9, 28))
|
||||
|
||||
case "bar":
|
||||
v.bar;
|
||||
>v.bar : Symbol(Bar.bar, Decl(narrowByParenthesizedSwitchExpression.ts, 10, 14))
|
||||
>v : Symbol(v, Decl(narrowByParenthesizedSwitchExpression.ts, 18, 5))
|
||||
>bar : Symbol(Bar.bar, Decl(narrowByParenthesizedSwitchExpression.ts, 10, 14))
|
||||
|
||||
break;
|
||||
|
||||
case "foo":
|
||||
v.foo;
|
||||
>v.foo : Symbol(Foo.foo, Decl(narrowByParenthesizedSwitchExpression.ts, 5, 14))
|
||||
>v : Symbol(v, Decl(narrowByParenthesizedSwitchExpression.ts, 18, 5))
|
||||
>foo : Symbol(Foo.foo, Decl(narrowByParenthesizedSwitchExpression.ts, 5, 14))
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
//// [tests/cases/compiler/narrowByParenthesizedSwitchExpression.ts] ////
|
||||
|
||||
=== narrowByParenthesizedSwitchExpression.ts ===
|
||||
interface Base {
|
||||
type: "foo" | "bar";
|
||||
>type : "foo" | "bar"
|
||||
}
|
||||
|
||||
interface Foo extends Base {
|
||||
type: "foo";
|
||||
>type : "foo"
|
||||
|
||||
foo: string;
|
||||
>foo : string
|
||||
}
|
||||
|
||||
interface Bar extends Base {
|
||||
type: "bar";
|
||||
>type : "bar"
|
||||
|
||||
bar: number;
|
||||
>bar : number
|
||||
}
|
||||
|
||||
function getV(): Foo | Bar {
|
||||
>getV : () => Foo | Bar
|
||||
|
||||
return null!;
|
||||
>null! : never
|
||||
}
|
||||
|
||||
const v = getV();
|
||||
>v : Foo | Bar
|
||||
>getV() : Foo | Bar
|
||||
>getV : () => Foo | Bar
|
||||
|
||||
switch ((v.type)) {
|
||||
>(v.type) : "foo" | "bar"
|
||||
>v.type : "foo" | "bar"
|
||||
>v : Foo | Bar
|
||||
>type : "foo" | "bar"
|
||||
|
||||
case "bar":
|
||||
>"bar" : "bar"
|
||||
|
||||
v.bar;
|
||||
>v.bar : number
|
||||
>v : Bar
|
||||
>bar : number
|
||||
|
||||
break;
|
||||
|
||||
case "foo":
|
||||
>"foo" : "foo"
|
||||
|
||||
v.foo;
|
||||
>v.foo : string
|
||||
>v : Foo
|
||||
>foo : string
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
interface Base {
|
||||
type: "foo" | "bar";
|
||||
}
|
||||
|
||||
interface Foo extends Base {
|
||||
type: "foo";
|
||||
foo: string;
|
||||
}
|
||||
|
||||
interface Bar extends Base {
|
||||
type: "bar";
|
||||
bar: number;
|
||||
}
|
||||
|
||||
function getV(): Foo | Bar {
|
||||
return null!;
|
||||
}
|
||||
|
||||
const v = getV();
|
||||
|
||||
switch ((v.type)) {
|
||||
case "bar":
|
||||
v.bar;
|
||||
break;
|
||||
|
||||
case "foo":
|
||||
v.foo;
|
||||
break;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user