mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-10 00:20:22 -06:00
Fixed control flow Analysis of aliased discriminants with parenthesized initializers (#61788)
This commit is contained in:
parent
48244d89f8
commit
4a957b74ea
@ -29379,26 +29379,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const symbol = getResolvedSymbol(expr);
|
||||
if (isConstantVariable(symbol)) {
|
||||
const declaration = symbol.valueDeclaration!;
|
||||
let initializer = getCandidateVariableDeclarationInitializer(declaration);
|
||||
// Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind'
|
||||
if (
|
||||
isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) &&
|
||||
isMatchingReference(reference, declaration.initializer.expression)
|
||||
) {
|
||||
return declaration.initializer;
|
||||
if (initializer && isAccessExpression(initializer) && isMatchingReference(reference, initializer.expression)) {
|
||||
return initializer;
|
||||
}
|
||||
// Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind'
|
||||
if (isBindingElement(declaration) && !declaration.initializer) {
|
||||
const parent = declaration.parent.parent;
|
||||
if (
|
||||
isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) &&
|
||||
isMatchingReference(reference, parent.initializer)
|
||||
) {
|
||||
initializer = getCandidateVariableDeclarationInitializer(declaration.parent.parent);
|
||||
if (initializer && (isIdentifier(initializer) || isAccessExpression(initializer)) && isMatchingReference(reference, initializer)) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
||||
function getCandidateVariableDeclarationInitializer(node: Node) {
|
||||
return isVariableDeclaration(node) && !node.type && node.initializer ? skipParentheses(node.initializer) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) {
|
||||
|
||||
292
tests/baselines/reference/controlFlowAliasing2.symbols
Normal file
292
tests/baselines/reference/controlFlowAliasing2.symbols
Normal file
@ -0,0 +1,292 @@
|
||||
//// [tests/cases/conformance/controlFlow/controlFlowAliasing2.ts] ////
|
||||
|
||||
=== controlFlowAliasing2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/61784
|
||||
|
||||
type Test = TestA | TestB;
|
||||
>Test : Symbol(Test, Decl(controlFlowAliasing2.ts, 0, 0))
|
||||
>TestA : Symbol(TestA, Decl(controlFlowAliasing2.ts, 2, 26))
|
||||
>TestB : Symbol(TestB, Decl(controlFlowAliasing2.ts, 7, 1))
|
||||
|
||||
interface TestA {
|
||||
>TestA : Symbol(TestA, Decl(controlFlowAliasing2.ts, 2, 26))
|
||||
|
||||
type: 'a';
|
||||
>type : Symbol(TestA.type, Decl(controlFlowAliasing2.ts, 4, 17))
|
||||
|
||||
name: string;
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
interface TestB {
|
||||
>TestB : Symbol(TestB, Decl(controlFlowAliasing2.ts, 7, 1))
|
||||
|
||||
type: 'b';
|
||||
>type : Symbol(TestB.type, Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
value: number;
|
||||
>value : Symbol(TestB.value, Decl(controlFlowAliasing2.ts, 10, 12))
|
||||
}
|
||||
|
||||
function _tcb1(this: { test: Test }) {
|
||||
>_tcb1 : Symbol(_tcb1, Decl(controlFlowAliasing2.ts, 12, 1))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>Test : Symbol(Test, Decl(controlFlowAliasing2.ts, 0, 0))
|
||||
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 16, 7))
|
||||
>(((this).test)).type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if (_t1 === "a") {
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 16, 7))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 22, 7))
|
||||
>this.test.type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if (_t2 === "a") {
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 22, 7))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 28, 7))
|
||||
>this.test.type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if (testType === "a") {
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 28, 7))
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb2(this: { test: Test }) {
|
||||
>_tcb2 : Symbol(_tcb2, Decl(controlFlowAliasing2.ts, 32, 1))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>Test : Symbol(Test, Decl(controlFlowAliasing2.ts, 0, 0))
|
||||
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 36, 7))
|
||||
>(((this).test)).type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if ("a" === _t1) {
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 36, 7))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 42, 7))
|
||||
>this.test.type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if ("a" === _t2) {
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 42, 7))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 48, 7))
|
||||
>this.test.type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
|
||||
if ("a" === testType) {
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 48, 7))
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb3(this: { test: Test }) {
|
||||
>_tcb3 : Symbol(_tcb3, Decl(controlFlowAliasing2.ts, 52, 1))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>Test : Symbol(Test, Decl(controlFlowAliasing2.ts, 0, 0))
|
||||
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 55, 9))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
|
||||
if (_t1 === "a") {
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 55, 9))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 61, 9))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
|
||||
if (_t2 === "a") {
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 61, 9))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 67, 9))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
|
||||
if (testType === "a") {
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 67, 9))
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb4(this: { test: Test }) {
|
||||
>_tcb4 : Symbol(_tcb4, Decl(controlFlowAliasing2.ts, 71, 1))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>Test : Symbol(Test, Decl(controlFlowAliasing2.ts, 0, 0))
|
||||
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 74, 9))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
|
||||
if ("a" === _t1) {
|
||||
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 74, 9))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 80, 9))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
|
||||
if ("a" === _t2) {
|
||||
>_t2 : Symbol(_t2, Decl(controlFlowAliasing2.ts, 80, 9))
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
>type : Symbol(type, Decl(controlFlowAliasing2.ts, 4, 17), Decl(controlFlowAliasing2.ts, 9, 17))
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 86, 9))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
|
||||
if ("a" === testType) {
|
||||
>testType : Symbol(testType, Decl(controlFlowAliasing2.ts, 86, 9))
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
>this.test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
|
||||
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
|
||||
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
|
||||
605
tests/baselines/reference/controlFlowAliasing2.types
Normal file
605
tests/baselines/reference/controlFlowAliasing2.types
Normal file
@ -0,0 +1,605 @@
|
||||
//// [tests/cases/conformance/controlFlow/controlFlowAliasing2.ts] ////
|
||||
|
||||
=== controlFlowAliasing2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/61784
|
||||
|
||||
type Test = TestA | TestB;
|
||||
>Test : Test
|
||||
> : ^^^^
|
||||
|
||||
interface TestA {
|
||||
type: 'a';
|
||||
>type : "a"
|
||||
> : ^^^
|
||||
|
||||
name: string;
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
interface TestB {
|
||||
type: 'b';
|
||||
>type : "b"
|
||||
> : ^^^
|
||||
|
||||
value: number;
|
||||
>value : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
function _tcb1(this: { test: Test }) {
|
||||
>_tcb1 : (this: { test: Test; }) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((((this).test)).type)) : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>((((this).test)).type) : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((this).test)).type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((this).test)) : Test
|
||||
> : ^^^^
|
||||
>((this).test) : Test
|
||||
> : ^^^^
|
||||
>(this).test : Test
|
||||
> : ^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if (_t1 === "a") {
|
||||
>_t1 === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test.type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if (_t2 === "a") {
|
||||
>_t2 === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test.type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if (testType === "a") {
|
||||
>testType === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : string
|
||||
> : ^^^^^^
|
||||
>this.test : TestA
|
||||
> : ^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb2(this: { test: Test }) {
|
||||
>_tcb2 : (this: { test: Test; }) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((((this).test)).type)) : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>((((this).test)).type) : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((this).test)).type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((this).test)) : Test
|
||||
> : ^^^^
|
||||
>((this).test) : Test
|
||||
> : ^^^^
|
||||
>(this).test : Test
|
||||
> : ^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if ("a" === _t1) {
|
||||
>"a" === _t1 : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test.type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if ("a" === _t2) {
|
||||
>"a" === _t2 : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test.type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
>type : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
if ("a" === testType) {
|
||||
>"a" === testType : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : string
|
||||
> : ^^^^^^
|
||||
>this.test : TestA
|
||||
> : ^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb3(this: { test: Test }) {
|
||||
>_tcb3 : (this: { test: Test; }) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
>type : any
|
||||
> : ^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((((this).test)))) : Test
|
||||
> : ^^^^
|
||||
>((((this).test))) : Test
|
||||
> : ^^^^
|
||||
>(((this).test)) : Test
|
||||
> : ^^^^
|
||||
>((this).test) : Test
|
||||
> : ^^^^
|
||||
>(this).test : Test
|
||||
> : ^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if (_t1 === "a") {
|
||||
>_t1 === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
>type : any
|
||||
> : ^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if (_t2 === "a") {
|
||||
>_t2 === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
>type : any
|
||||
> : ^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if (testType === "a") {
|
||||
>testType === "a" : boolean
|
||||
> : ^^^^^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : string
|
||||
> : ^^^^^^
|
||||
>this.test : TestA
|
||||
> : ^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb4(this: { test: Test }) {
|
||||
>_tcb4 : (this: { test: Test; }) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
>type : any
|
||||
> : ^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>(((((this).test)))) : Test
|
||||
> : ^^^^
|
||||
>((((this).test))) : Test
|
||||
> : ^^^^
|
||||
>(((this).test)) : Test
|
||||
> : ^^^^
|
||||
>((this).test) : Test
|
||||
> : ^^^^
|
||||
>(this).test : Test
|
||||
> : ^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if ("a" === _t1) {
|
||||
>"a" === _t1 : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>_t1 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
>type : any
|
||||
> : ^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if ("a" === _t2) {
|
||||
>"a" === _t2 : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>_t2 : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
(((((this).test)).name));
|
||||
>(((((this).test)).name)) : string
|
||||
> : ^^^^^^
|
||||
>((((this).test)).name) : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)).name : string
|
||||
> : ^^^^^^
|
||||
>(((this).test)) : TestA
|
||||
> : ^^^^^
|
||||
>((this).test) : TestA
|
||||
> : ^^^^^
|
||||
>(this).test : TestA
|
||||
> : ^^^^^
|
||||
>(this) : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
>type : any
|
||||
> : ^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
>this.test : Test
|
||||
> : ^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : Test
|
||||
> : ^^^^
|
||||
|
||||
if ("a" === testType) {
|
||||
>"a" === testType : boolean
|
||||
> : ^^^^^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>testType : "a" | "b"
|
||||
> : ^^^^^^^^^
|
||||
|
||||
this.test.name;
|
||||
>this.test.name : string
|
||||
> : ^^^^^^
|
||||
>this.test : TestA
|
||||
> : ^^^^^
|
||||
>this : { test: Test; }
|
||||
> : ^^^^^^^^ ^^^
|
||||
>test : TestA
|
||||
> : ^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
|
||||
96
tests/cases/conformance/controlFlow/controlFlowAliasing2.ts
Normal file
96
tests/cases/conformance/controlFlow/controlFlowAliasing2.ts
Normal file
@ -0,0 +1,96 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/61784
|
||||
|
||||
type Test = TestA | TestB;
|
||||
|
||||
interface TestA {
|
||||
type: 'a';
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface TestB {
|
||||
type: 'b';
|
||||
value: number;
|
||||
}
|
||||
|
||||
function _tcb1(this: { test: Test }) {
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
if (_t1 === "a") {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
if (_t2 === "a") {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
if (testType === "a") {
|
||||
this.test.name;
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb2(this: { test: Test }) {
|
||||
// TS generated by Angular's Type Check block
|
||||
const _t1 = (((((this).test)).type));
|
||||
if ("a" === _t1) {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const _t2 = this.test.type;
|
||||
if ("a" === _t2) {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const testType = this.test.type;
|
||||
if ("a" === testType) {
|
||||
this.test.name;
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb3(this: { test: Test }) {
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
if (_t1 === "a") {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
if (_t2 === "a") {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
if (testType === "a") {
|
||||
this.test.name;
|
||||
}
|
||||
}
|
||||
|
||||
function _tcb4(this: { test: Test }) {
|
||||
const { type: _t1 } = (((((this).test))));
|
||||
if ("a" === _t1) {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above, without the parenthesis
|
||||
const { type: _t2 } = this.test;
|
||||
if ("a" === _t2) {
|
||||
(((((this).test)).name));
|
||||
}
|
||||
|
||||
// Same as above without parenthesis at both places
|
||||
const { type: testType } = this.test;
|
||||
if ("a" === testType) {
|
||||
this.test.name;
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
Loading…
x
Reference in New Issue
Block a user