From 83971d0900b48a6c88c287b154a2c74bdc6409d0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 8 Jun 2016 10:51:32 -0700 Subject: [PATCH 1/5] Create intersection types in type guards for unrelated types --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 650bc488b0e1d..ea494725fc613 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7997,7 +7997,7 @@ namespace ts { const targetType = type.flags & TypeFlags.TypeParameter ? getApparentType(type) : type; return isTypeAssignableTo(candidate, targetType) ? candidate : isTypeAssignableTo(type, candidate) ? type : - neverType; + getIntersectionType([type, candidate]); } function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { From ea1bdff096cad9d21149f9f9713eb5e60e8949b5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 8 Jun 2016 11:41:34 -0700 Subject: [PATCH 2/5] Accept new baselines --- .../reference/instanceOfAssignability.types | 4 +-- .../stringLiteralTypesAsTags01.types | 4 +-- .../stringLiteralTypesAsTags02.types | 4 +-- .../stringLiteralTypesAsTags03.types | 4 +-- .../typeGuardsWithInstanceOf.errors.txt | 14 --------- .../typeGuardsWithInstanceOf.symbols | 26 ++++++++++++++++ .../reference/typeGuardsWithInstanceOf.types | 31 +++++++++++++++++++ 7 files changed, 65 insertions(+), 22 deletions(-) delete mode 100644 tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOf.symbols create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOf.types diff --git a/tests/baselines/reference/instanceOfAssignability.types b/tests/baselines/reference/instanceOfAssignability.types index 70d068fb0cc46..44ec45e206901 100644 --- a/tests/baselines/reference/instanceOfAssignability.types +++ b/tests/baselines/reference/instanceOfAssignability.types @@ -133,8 +133,8 @@ function fn5(x: Derived1) { // 1.5: y: Derived1 // Want: ??? let y = x; ->y : never ->x : never +>y : Derived1 & Derived2 +>x : Derived1 & Derived2 } } diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.types b/tests/baselines/reference/stringLiteralTypesAsTags01.types index 7b8ac0a8c02b8..64b099b34f2fa 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.types @@ -116,6 +116,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : never ->x : never +>d : A & B +>x : A & B } diff --git a/tests/baselines/reference/stringLiteralTypesAsTags02.types b/tests/baselines/reference/stringLiteralTypesAsTags02.types index 290402cd299cb..92b294a249895 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags02.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags02.types @@ -110,6 +110,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : never ->x : never +>d : A & B +>x : A & B } diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.types b/tests/baselines/reference/stringLiteralTypesAsTags03.types index 9d004982dda07..49ae3da4be033 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags03.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.types @@ -113,6 +113,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : never ->x : never +>d : A & B +>x : A & B } diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt deleted file mode 100644 index dfcb8a598dae5..0000000000000 --- a/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'never'. - - -==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ==== - interface I { global: string; } - var result: I; - var result2: I; - - if (!(result instanceof RegExp)) { - result = result2; - } else if (!result.global) { - ~~~~~~ -!!! error TS2339: Property 'global' does not exist on type 'never'. - } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.symbols b/tests/baselines/reference/typeGuardsWithInstanceOf.symbols new file mode 100644 index 0000000000000..6d1667a651995 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOf.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts === +interface I { global: string; } +>I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) +>global : Symbol(I.global, Decl(typeGuardsWithInstanceOf.ts, 0, 13)) + +var result: I; +>result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) +>I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) + +var result2: I; +>result2 : Symbol(result2, Decl(typeGuardsWithInstanceOf.ts, 2, 3)) +>I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) + +if (!(result instanceof RegExp)) { +>result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + result = result2; +>result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) +>result2 : Symbol(result2, Decl(typeGuardsWithInstanceOf.ts, 2, 3)) + +} else if (!result.global) { +>result.global : Symbol(global, Decl(typeGuardsWithInstanceOf.ts, 0, 13), Decl(lib.d.ts, --, --)) +>result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) +>global : Symbol(global, Decl(typeGuardsWithInstanceOf.ts, 0, 13), Decl(lib.d.ts, --, --)) +} diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.types b/tests/baselines/reference/typeGuardsWithInstanceOf.types new file mode 100644 index 0000000000000..f54498f93c875 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOf.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts === +interface I { global: string; } +>I : I +>global : string + +var result: I; +>result : I +>I : I + +var result2: I; +>result2 : I +>I : I + +if (!(result instanceof RegExp)) { +>!(result instanceof RegExp) : boolean +>(result instanceof RegExp) : boolean +>result instanceof RegExp : boolean +>result : I +>RegExp : RegExpConstructor + + result = result2; +>result = result2 : I +>result : I +>result2 : I + +} else if (!result.global) { +>!result.global : boolean +>result.global : string & boolean +>result : I & RegExp +>global : string & boolean +} From a57ee29ff7f9ddef02f12d4540928b11adc9333f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 8 Jun 2016 11:41:44 -0700 Subject: [PATCH 3/5] Add tests --- .../reference/typeGuardIntersectionTypes.js | 181 ++++++++++ .../typeGuardIntersectionTypes.symbols | 262 +++++++++++++++ .../typeGuardIntersectionTypes.types | 310 ++++++++++++++++++ .../typeGuards/typeGuardIntersectionTypes.ts | 115 +++++++ 4 files changed, 868 insertions(+) create mode 100644 tests/baselines/reference/typeGuardIntersectionTypes.js create mode 100644 tests/baselines/reference/typeGuardIntersectionTypes.symbols create mode 100644 tests/baselines/reference/typeGuardIntersectionTypes.types create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.js b/tests/baselines/reference/typeGuardIntersectionTypes.js new file mode 100644 index 0000000000000..16d35c438893b --- /dev/null +++ b/tests/baselines/reference/typeGuardIntersectionTypes.js @@ -0,0 +1,181 @@ +//// [typeGuardIntersectionTypes.ts] + +interface X { + x: string; +} + +interface Y { + y: string; +} + +interface Z { + z: string; +} + +declare function isX(obj: any): obj is X; +declare function isY(obj: any): obj is Y; +declare function isZ(obj: any): obj is Z; + +function f1(obj: Object) { + if (isX(obj) || isY(obj) || isZ(obj)) { + obj; + } + if (isX(obj) && isY(obj) && isZ(obj)) { + obj; + } +} + +// Repro from #8911 + +// two interfaces +interface A { + a: string; +} + +interface B { + b: string; +} + +// a type guard for B +function isB(toTest: any): toTest is B { + return toTest && toTest.b; +} + +// a function that turns an A into an A & B +function union(a: A): A & B | null { + if (isB(a)) { + return a; + } else { + return null; + } +} + +// Repro from #9011 + +declare function log(s: string): void; + +// Supported beast features +interface Beast { wings?: boolean; legs?: number } +interface Legged { legs: number; } +interface Winged { wings: boolean; } + +// Beast feature detection via user-defined type guards +function hasLegs(x: Beast): x is Legged { return x && typeof x.legs === 'number'; } +function hasWings(x: Beast): x is Winged { return x && !!x.wings; } + +// Function to identify a given beast by detecting its features +function identifyBeast(beast: Beast) { + + // All beasts with legs + if (hasLegs(beast)) { + + // All winged beasts with legs + if (hasWings(beast)) { + if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + log(`pegasus - 4 legs, wings`); + } + else if (beast.legs === 2) { // ERROR TS2339... + log(`bird - 2 legs, wings`); + } + else { + log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + } + } + + // All non-winged beasts with legs + else { + log(`manbearpig - ${beast.legs} legs, no wings`); + } + } + + // All beasts without legs + else { + if (hasWings(beast)) { + log(`quetzalcoatl - no legs, wings`) + } + else { + log(`snake - no legs, no wings`) + } + } +} + +function beastFoo(beast: Object) { + if (hasWings(beast) && hasLegs(beast)) { + beast // beast is Legged + // ideally, beast would be Winged && Legged here... + } + else { + beast + } + + if (hasLegs(beast) && hasWings(beast)) { + beast // beast is Winged + // ideally, beast would be Legged && Winged here... + } +} + +//// [typeGuardIntersectionTypes.js] +function f1(obj) { + if (isX(obj) || isY(obj) || isZ(obj)) { + obj; + } + if (isX(obj) && isY(obj) && isZ(obj)) { + obj; + } +} +// a type guard for B +function isB(toTest) { + return toTest && toTest.b; +} +// a function that turns an A into an A & B +function union(a) { + if (isB(a)) { + return a; + } + else { + return null; + } +} +// Beast feature detection via user-defined type guards +function hasLegs(x) { return x && typeof x.legs === 'number'; } +function hasWings(x) { return x && !!x.wings; } +// Function to identify a given beast by detecting its features +function identifyBeast(beast) { + // All beasts with legs + if (hasLegs(beast)) { + // All winged beasts with legs + if (hasWings(beast)) { + if (beast.legs === 4) { + log("pegasus - 4 legs, wings"); + } + else if (beast.legs === 2) { + log("bird - 2 legs, wings"); + } + else { + log("unknown - " + beast.legs + " legs, wings"); // ERROR TS2339... + } + } + else { + log("manbearpig - " + beast.legs + " legs, no wings"); + } + } + else { + if (hasWings(beast)) { + log("quetzalcoatl - no legs, wings"); + } + else { + log("snake - no legs, no wings"); + } + } +} +function beastFoo(beast) { + if (hasWings(beast) && hasLegs(beast)) { + beast; // beast is Legged + } + else { + beast; + } + if (hasLegs(beast) && hasWings(beast)) { + beast; // beast is Winged + } +} diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.symbols b/tests/baselines/reference/typeGuardIntersectionTypes.symbols new file mode 100644 index 0000000000000..c59d972cd3075 --- /dev/null +++ b/tests/baselines/reference/typeGuardIntersectionTypes.symbols @@ -0,0 +1,262 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts === + +interface X { +>X : Symbol(X, Decl(typeGuardIntersectionTypes.ts, 0, 0)) + + x: string; +>x : Symbol(X.x, Decl(typeGuardIntersectionTypes.ts, 1, 13)) +} + +interface Y { +>Y : Symbol(Y, Decl(typeGuardIntersectionTypes.ts, 3, 1)) + + y: string; +>y : Symbol(Y.y, Decl(typeGuardIntersectionTypes.ts, 5, 13)) +} + +interface Z { +>Z : Symbol(Z, Decl(typeGuardIntersectionTypes.ts, 7, 1)) + + z: string; +>z : Symbol(Z.z, Decl(typeGuardIntersectionTypes.ts, 9, 13)) +} + +declare function isX(obj: any): obj is X; +>isX : Symbol(isX, Decl(typeGuardIntersectionTypes.ts, 11, 1)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 13, 21)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 13, 21)) +>X : Symbol(X, Decl(typeGuardIntersectionTypes.ts, 0, 0)) + +declare function isY(obj: any): obj is Y; +>isY : Symbol(isY, Decl(typeGuardIntersectionTypes.ts, 13, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 14, 21)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 14, 21)) +>Y : Symbol(Y, Decl(typeGuardIntersectionTypes.ts, 3, 1)) + +declare function isZ(obj: any): obj is Z; +>isZ : Symbol(isZ, Decl(typeGuardIntersectionTypes.ts, 14, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 15, 21)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 15, 21)) +>Z : Symbol(Z, Decl(typeGuardIntersectionTypes.ts, 7, 1)) + +function f1(obj: Object) { +>f1 : Symbol(f1, Decl(typeGuardIntersectionTypes.ts, 15, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + if (isX(obj) || isY(obj) || isZ(obj)) { +>isX : Symbol(isX, Decl(typeGuardIntersectionTypes.ts, 11, 1)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) +>isY : Symbol(isY, Decl(typeGuardIntersectionTypes.ts, 13, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) +>isZ : Symbol(isZ, Decl(typeGuardIntersectionTypes.ts, 14, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) + + obj; +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) + } + if (isX(obj) && isY(obj) && isZ(obj)) { +>isX : Symbol(isX, Decl(typeGuardIntersectionTypes.ts, 11, 1)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) +>isY : Symbol(isY, Decl(typeGuardIntersectionTypes.ts, 13, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) +>isZ : Symbol(isZ, Decl(typeGuardIntersectionTypes.ts, 14, 41)) +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) + + obj; +>obj : Symbol(obj, Decl(typeGuardIntersectionTypes.ts, 17, 12)) + } +} + +// Repro from #8911 + +// two interfaces +interface A { +>A : Symbol(A, Decl(typeGuardIntersectionTypes.ts, 24, 1)) + + a: string; +>a : Symbol(A.a, Decl(typeGuardIntersectionTypes.ts, 29, 13)) +} + +interface B { +>B : Symbol(B, Decl(typeGuardIntersectionTypes.ts, 31, 1)) + + b: string; +>b : Symbol(B.b, Decl(typeGuardIntersectionTypes.ts, 33, 13)) +} + +// a type guard for B +function isB(toTest: any): toTest is B { +>isB : Symbol(isB, Decl(typeGuardIntersectionTypes.ts, 35, 1)) +>toTest : Symbol(toTest, Decl(typeGuardIntersectionTypes.ts, 38, 13)) +>toTest : Symbol(toTest, Decl(typeGuardIntersectionTypes.ts, 38, 13)) +>B : Symbol(B, Decl(typeGuardIntersectionTypes.ts, 31, 1)) + + return toTest && toTest.b; +>toTest : Symbol(toTest, Decl(typeGuardIntersectionTypes.ts, 38, 13)) +>toTest : Symbol(toTest, Decl(typeGuardIntersectionTypes.ts, 38, 13)) +} + +// a function that turns an A into an A & B +function union(a: A): A & B | null { +>union : Symbol(union, Decl(typeGuardIntersectionTypes.ts, 40, 1)) +>a : Symbol(a, Decl(typeGuardIntersectionTypes.ts, 43, 15)) +>A : Symbol(A, Decl(typeGuardIntersectionTypes.ts, 24, 1)) +>A : Symbol(A, Decl(typeGuardIntersectionTypes.ts, 24, 1)) +>B : Symbol(B, Decl(typeGuardIntersectionTypes.ts, 31, 1)) + + if (isB(a)) { +>isB : Symbol(isB, Decl(typeGuardIntersectionTypes.ts, 35, 1)) +>a : Symbol(a, Decl(typeGuardIntersectionTypes.ts, 43, 15)) + + return a; +>a : Symbol(a, Decl(typeGuardIntersectionTypes.ts, 43, 15)) + + } else { + return null; + } +} + +// Repro from #9011 + +declare function log(s: string): void; +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) +>s : Symbol(s, Decl(typeGuardIntersectionTypes.ts, 53, 21)) + +// Supported beast features +interface Beast { wings?: boolean; legs?: number } +>Beast : Symbol(Beast, Decl(typeGuardIntersectionTypes.ts, 53, 38)) +>wings : Symbol(Beast.wings, Decl(typeGuardIntersectionTypes.ts, 56, 21)) +>legs : Symbol(Beast.legs, Decl(typeGuardIntersectionTypes.ts, 56, 38)) + +interface Legged { legs: number; } +>Legged : Symbol(Legged, Decl(typeGuardIntersectionTypes.ts, 56, 54)) +>legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) + +interface Winged { wings: boolean; } +>Winged : Symbol(Winged, Decl(typeGuardIntersectionTypes.ts, 57, 37)) +>wings : Symbol(Winged.wings, Decl(typeGuardIntersectionTypes.ts, 58, 21)) + +// Beast feature detection via user-defined type guards +function hasLegs(x: Beast): x is Legged { return x && typeof x.legs === 'number'; } +>hasLegs : Symbol(hasLegs, Decl(typeGuardIntersectionTypes.ts, 58, 39)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 61, 17)) +>Beast : Symbol(Beast, Decl(typeGuardIntersectionTypes.ts, 53, 38)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 61, 17)) +>Legged : Symbol(Legged, Decl(typeGuardIntersectionTypes.ts, 56, 54)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 61, 17)) +>x.legs : Symbol(Beast.legs, Decl(typeGuardIntersectionTypes.ts, 56, 38)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 61, 17)) +>legs : Symbol(Beast.legs, Decl(typeGuardIntersectionTypes.ts, 56, 38)) + +function hasWings(x: Beast): x is Winged { return x && !!x.wings; } +>hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 62, 18)) +>Beast : Symbol(Beast, Decl(typeGuardIntersectionTypes.ts, 53, 38)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 62, 18)) +>Winged : Symbol(Winged, Decl(typeGuardIntersectionTypes.ts, 57, 37)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 62, 18)) +>x.wings : Symbol(Beast.wings, Decl(typeGuardIntersectionTypes.ts, 56, 21)) +>x : Symbol(x, Decl(typeGuardIntersectionTypes.ts, 62, 18)) +>wings : Symbol(Beast.wings, Decl(typeGuardIntersectionTypes.ts, 56, 21)) + +// Function to identify a given beast by detecting its features +function identifyBeast(beast: Beast) { +>identifyBeast : Symbol(identifyBeast, Decl(typeGuardIntersectionTypes.ts, 62, 67)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) +>Beast : Symbol(Beast, Decl(typeGuardIntersectionTypes.ts, 53, 38)) + + // All beasts with legs + if (hasLegs(beast)) { +>hasLegs : Symbol(hasLegs, Decl(typeGuardIntersectionTypes.ts, 58, 39)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) + + // All winged beasts with legs + if (hasWings(beast)) { +>hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) + + if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. +>beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) +>legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) + + log(`pegasus - 4 legs, wings`); +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) + } + else if (beast.legs === 2) { // ERROR TS2339... +>beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) +>legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) + + log(`bird - 2 legs, wings`); +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) + } + else { + log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) +>beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) +>legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) + } + } + + // All non-winged beasts with legs + else { + log(`manbearpig - ${beast.legs} legs, no wings`); +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) +>beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) +>legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) + } + } + + // All beasts without legs + else { + if (hasWings(beast)) { +>hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) + + log(`quetzalcoatl - no legs, wings`) +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) + } + else { + log(`snake - no legs, no wings`) +>log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) + } + } +} + +function beastFoo(beast: Object) { +>beastFoo : Symbol(beastFoo, Decl(typeGuardIntersectionTypes.ts, 98, 1)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + if (hasWings(beast) && hasLegs(beast)) { +>hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) +>hasLegs : Symbol(hasLegs, Decl(typeGuardIntersectionTypes.ts, 58, 39)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) + + beast // beast is Legged +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) + + // ideally, beast would be Winged && Legged here... + } + else { + beast +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) + } + + if (hasLegs(beast) && hasWings(beast)) { +>hasLegs : Symbol(hasLegs, Decl(typeGuardIntersectionTypes.ts, 58, 39)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) +>hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) + + beast // beast is Winged +>beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) + + // ideally, beast would be Legged && Winged here... + } +} diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.types b/tests/baselines/reference/typeGuardIntersectionTypes.types new file mode 100644 index 0000000000000..4018036c5cecc --- /dev/null +++ b/tests/baselines/reference/typeGuardIntersectionTypes.types @@ -0,0 +1,310 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts === + +interface X { +>X : X + + x: string; +>x : string +} + +interface Y { +>Y : Y + + y: string; +>y : string +} + +interface Z { +>Z : Z + + z: string; +>z : string +} + +declare function isX(obj: any): obj is X; +>isX : (obj: any) => obj is X +>obj : any +>obj : any +>X : X + +declare function isY(obj: any): obj is Y; +>isY : (obj: any) => obj is Y +>obj : any +>obj : any +>Y : Y + +declare function isZ(obj: any): obj is Z; +>isZ : (obj: any) => obj is Z +>obj : any +>obj : any +>Z : Z + +function f1(obj: Object) { +>f1 : (obj: Object) => void +>obj : Object +>Object : Object + + if (isX(obj) || isY(obj) || isZ(obj)) { +>isX(obj) || isY(obj) || isZ(obj) : boolean +>isX(obj) || isY(obj) : boolean +>isX(obj) : boolean +>isX : (obj: any) => obj is X +>obj : Object +>isY(obj) : boolean +>isY : (obj: any) => obj is Y +>obj : Object +>isZ(obj) : boolean +>isZ : (obj: any) => obj is Z +>obj : Object + + obj; +>obj : X | Y | Z + } + if (isX(obj) && isY(obj) && isZ(obj)) { +>isX(obj) && isY(obj) && isZ(obj) : boolean +>isX(obj) && isY(obj) : boolean +>isX(obj) : boolean +>isX : (obj: any) => obj is X +>obj : Object +>isY(obj) : boolean +>isY : (obj: any) => obj is Y +>obj : X +>isZ(obj) : boolean +>isZ : (obj: any) => obj is Z +>obj : X & Y + + obj; +>obj : X & Y & Z + } +} + +// Repro from #8911 + +// two interfaces +interface A { +>A : A + + a: string; +>a : string +} + +interface B { +>B : B + + b: string; +>b : string +} + +// a type guard for B +function isB(toTest: any): toTest is B { +>isB : (toTest: any) => toTest is B +>toTest : any +>toTest : any +>B : B + + return toTest && toTest.b; +>toTest && toTest.b : any +>toTest : any +>toTest.b : any +>toTest : any +>b : any +} + +// a function that turns an A into an A & B +function union(a: A): A & B | null { +>union : (a: A) => (A & B) | null +>a : A +>A : A +>A : A +>B : B +>null : null + + if (isB(a)) { +>isB(a) : boolean +>isB : (toTest: any) => toTest is B +>a : A + + return a; +>a : A & B + + } else { + return null; +>null : null + } +} + +// Repro from #9011 + +declare function log(s: string): void; +>log : (s: string) => void +>s : string + +// Supported beast features +interface Beast { wings?: boolean; legs?: number } +>Beast : Beast +>wings : boolean | undefined +>legs : number | undefined + +interface Legged { legs: number; } +>Legged : Legged +>legs : number + +interface Winged { wings: boolean; } +>Winged : Winged +>wings : boolean + +// Beast feature detection via user-defined type guards +function hasLegs(x: Beast): x is Legged { return x && typeof x.legs === 'number'; } +>hasLegs : (x: Beast) => x is Legged +>x : Beast +>Beast : Beast +>x : any +>Legged : Legged +>x && typeof x.legs === 'number' : boolean +>x : Beast +>typeof x.legs === 'number' : boolean +>typeof x.legs : string +>x.legs : number | undefined +>x : Beast +>legs : number | undefined +>'number' : string + +function hasWings(x: Beast): x is Winged { return x && !!x.wings; } +>hasWings : (x: Beast) => x is Winged +>x : Beast +>Beast : Beast +>x : any +>Winged : Winged +>x && !!x.wings : boolean +>x : Beast +>!!x.wings : boolean +>!x.wings : boolean +>x.wings : boolean | undefined +>x : Beast +>wings : boolean | undefined + +// Function to identify a given beast by detecting its features +function identifyBeast(beast: Beast) { +>identifyBeast : (beast: Beast) => void +>beast : Beast +>Beast : Beast + + // All beasts with legs + if (hasLegs(beast)) { +>hasLegs(beast) : boolean +>hasLegs : (x: Beast) => x is Legged +>beast : Beast + + // All winged beasts with legs + if (hasWings(beast)) { +>hasWings(beast) : boolean +>hasWings : (x: Beast) => x is Winged +>beast : Legged + + if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. +>beast.legs === 4 : boolean +>beast.legs : number +>beast : Legged & Winged +>legs : number +>4 : number + + log(`pegasus - 4 legs, wings`); +>log(`pegasus - 4 legs, wings`) : void +>log : (s: string) => void +>`pegasus - 4 legs, wings` : string + } + else if (beast.legs === 2) { // ERROR TS2339... +>beast.legs === 2 : boolean +>beast.legs : number +>beast : Legged & Winged +>legs : number +>2 : number + + log(`bird - 2 legs, wings`); +>log(`bird - 2 legs, wings`) : void +>log : (s: string) => void +>`bird - 2 legs, wings` : string + } + else { + log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... +>log(`unknown - ${beast.legs} legs, wings`) : void +>log : (s: string) => void +>`unknown - ${beast.legs} legs, wings` : string +>beast.legs : number +>beast : Legged & Winged +>legs : number + } + } + + // All non-winged beasts with legs + else { + log(`manbearpig - ${beast.legs} legs, no wings`); +>log(`manbearpig - ${beast.legs} legs, no wings`) : void +>log : (s: string) => void +>`manbearpig - ${beast.legs} legs, no wings` : string +>beast.legs : number +>beast : Legged +>legs : number + } + } + + // All beasts without legs + else { + if (hasWings(beast)) { +>hasWings(beast) : boolean +>hasWings : (x: Beast) => x is Winged +>beast : Beast + + log(`quetzalcoatl - no legs, wings`) +>log(`quetzalcoatl - no legs, wings`) : void +>log : (s: string) => void +>`quetzalcoatl - no legs, wings` : string + } + else { + log(`snake - no legs, no wings`) +>log(`snake - no legs, no wings`) : void +>log : (s: string) => void +>`snake - no legs, no wings` : string + } + } +} + +function beastFoo(beast: Object) { +>beastFoo : (beast: Object) => void +>beast : Object +>Object : Object + + if (hasWings(beast) && hasLegs(beast)) { +>hasWings(beast) && hasLegs(beast) : boolean +>hasWings(beast) : boolean +>hasWings : (x: Beast) => x is Winged +>beast : Object +>hasLegs(beast) : boolean +>hasLegs : (x: Beast) => x is Legged +>beast : Winged + + beast // beast is Legged +>beast : Winged & Legged + + // ideally, beast would be Winged && Legged here... + } + else { + beast +>beast : Object + } + + if (hasLegs(beast) && hasWings(beast)) { +>hasLegs(beast) && hasWings(beast) : boolean +>hasLegs(beast) : boolean +>hasLegs : (x: Beast) => x is Legged +>beast : Object +>hasWings(beast) : boolean +>hasWings : (x: Beast) => x is Winged +>beast : Legged + + beast // beast is Winged +>beast : Legged & Winged + + // ideally, beast would be Legged && Winged here... + } +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts new file mode 100644 index 0000000000000..efde587e5e5d5 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts @@ -0,0 +1,115 @@ +// @strictNullChecks: true + +interface X { + x: string; +} + +interface Y { + y: string; +} + +interface Z { + z: string; +} + +declare function isX(obj: any): obj is X; +declare function isY(obj: any): obj is Y; +declare function isZ(obj: any): obj is Z; + +function f1(obj: Object) { + if (isX(obj) || isY(obj) || isZ(obj)) { + obj; + } + if (isX(obj) && isY(obj) && isZ(obj)) { + obj; + } +} + +// Repro from #8911 + +// two interfaces +interface A { + a: string; +} + +interface B { + b: string; +} + +// a type guard for B +function isB(toTest: any): toTest is B { + return toTest && toTest.b; +} + +// a function that turns an A into an A & B +function union(a: A): A & B | null { + if (isB(a)) { + return a; + } else { + return null; + } +} + +// Repro from #9011 + +declare function log(s: string): void; + +// Supported beast features +interface Beast { wings?: boolean; legs?: number } +interface Legged { legs: number; } +interface Winged { wings: boolean; } + +// Beast feature detection via user-defined type guards +function hasLegs(x: Beast): x is Legged { return x && typeof x.legs === 'number'; } +function hasWings(x: Beast): x is Winged { return x && !!x.wings; } + +// Function to identify a given beast by detecting its features +function identifyBeast(beast: Beast) { + + // All beasts with legs + if (hasLegs(beast)) { + + // All winged beasts with legs + if (hasWings(beast)) { + if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + log(`pegasus - 4 legs, wings`); + } + else if (beast.legs === 2) { // ERROR TS2339... + log(`bird - 2 legs, wings`); + } + else { + log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + } + } + + // All non-winged beasts with legs + else { + log(`manbearpig - ${beast.legs} legs, no wings`); + } + } + + // All beasts without legs + else { + if (hasWings(beast)) { + log(`quetzalcoatl - no legs, wings`) + } + else { + log(`snake - no legs, no wings`) + } + } +} + +function beastFoo(beast: Object) { + if (hasWings(beast) && hasLegs(beast)) { + beast // beast is Legged + // ideally, beast would be Winged && Legged here... + } + else { + beast + } + + if (hasLegs(beast) && hasWings(beast)) { + beast // beast is Winged + // ideally, beast would be Legged && Winged here... + } +} \ No newline at end of file From d182a5978223f80154f4bd1b54e191b3546cf8ba Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 8 Jun 2016 16:35:39 -0700 Subject: [PATCH 4/5] Fix comments in tests --- .../reference/typeGuardIntersectionTypes.js | 20 +++++++++---------- .../typeGuardIntersectionTypes.symbols | 16 ++++++--------- .../typeGuardIntersectionTypes.types | 16 ++++++--------- .../typeGuards/typeGuardIntersectionTypes.ts | 14 ++++++------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.js b/tests/baselines/reference/typeGuardIntersectionTypes.js index 16d35c438893b..6c46b982024f6 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.js +++ b/tests/baselines/reference/typeGuardIntersectionTypes.js @@ -71,14 +71,14 @@ function identifyBeast(beast: Beast) { // All winged beasts with legs if (hasWings(beast)) { - if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + if (beast.legs === 4) { log(`pegasus - 4 legs, wings`); } - else if (beast.legs === 2) { // ERROR TS2339... + else if (beast.legs === 2) { log(`bird - 2 legs, wings`); } else { - log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + log(`unknown - ${beast.legs} legs, wings`); } } @@ -101,16 +101,14 @@ function identifyBeast(beast: Beast) { function beastFoo(beast: Object) { if (hasWings(beast) && hasLegs(beast)) { - beast // beast is Legged - // ideally, beast would be Winged && Legged here... + beast; // Winged & Legged } else { - beast + beast; } if (hasLegs(beast) && hasWings(beast)) { - beast // beast is Winged - // ideally, beast would be Legged && Winged here... + beast; // Legged & Winged } } @@ -152,7 +150,7 @@ function identifyBeast(beast) { log("bird - 2 legs, wings"); } else { - log("unknown - " + beast.legs + " legs, wings"); // ERROR TS2339... + log("unknown - " + beast.legs + " legs, wings"); } } else { @@ -170,12 +168,12 @@ function identifyBeast(beast) { } function beastFoo(beast) { if (hasWings(beast) && hasLegs(beast)) { - beast; // beast is Legged + beast; // Winged & Legged } else { beast; } if (hasLegs(beast) && hasWings(beast)) { - beast; // beast is Winged + beast; // Legged & Winged } } diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.symbols b/tests/baselines/reference/typeGuardIntersectionTypes.symbols index c59d972cd3075..707fb95b339ec 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.symbols +++ b/tests/baselines/reference/typeGuardIntersectionTypes.symbols @@ -176,7 +176,7 @@ function identifyBeast(beast: Beast) { >hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) - if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + if (beast.legs === 4) { >beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) >legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) @@ -184,7 +184,7 @@ function identifyBeast(beast: Beast) { log(`pegasus - 4 legs, wings`); >log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) } - else if (beast.legs === 2) { // ERROR TS2339... + else if (beast.legs === 2) { >beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) >legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) @@ -193,7 +193,7 @@ function identifyBeast(beast: Beast) { >log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) } else { - log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + log(`unknown - ${beast.legs} legs, wings`); >log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) >beast.legs : Symbol(Legged.legs, Decl(typeGuardIntersectionTypes.ts, 57, 21)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 65, 23)) @@ -238,13 +238,11 @@ function beastFoo(beast: Object) { >hasLegs : Symbol(hasLegs, Decl(typeGuardIntersectionTypes.ts, 58, 39)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) - beast // beast is Legged + beast; // Winged & Legged >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) - - // ideally, beast would be Winged && Legged here... } else { - beast + beast; >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) } @@ -254,9 +252,7 @@ function beastFoo(beast: Object) { >hasWings : Symbol(hasWings, Decl(typeGuardIntersectionTypes.ts, 61, 83)) >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) - beast // beast is Winged + beast; // Legged & Winged >beast : Symbol(beast, Decl(typeGuardIntersectionTypes.ts, 100, 18)) - - // ideally, beast would be Legged && Winged here... } } diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.types b/tests/baselines/reference/typeGuardIntersectionTypes.types index 4018036c5cecc..5ce768d4a5ee5 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.types +++ b/tests/baselines/reference/typeGuardIntersectionTypes.types @@ -201,7 +201,7 @@ function identifyBeast(beast: Beast) { >hasWings : (x: Beast) => x is Winged >beast : Legged - if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + if (beast.legs === 4) { >beast.legs === 4 : boolean >beast.legs : number >beast : Legged & Winged @@ -213,7 +213,7 @@ function identifyBeast(beast: Beast) { >log : (s: string) => void >`pegasus - 4 legs, wings` : string } - else if (beast.legs === 2) { // ERROR TS2339... + else if (beast.legs === 2) { >beast.legs === 2 : boolean >beast.legs : number >beast : Legged & Winged @@ -226,7 +226,7 @@ function identifyBeast(beast: Beast) { >`bird - 2 legs, wings` : string } else { - log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + log(`unknown - ${beast.legs} legs, wings`); >log(`unknown - ${beast.legs} legs, wings`) : void >log : (s: string) => void >`unknown - ${beast.legs} legs, wings` : string @@ -283,13 +283,11 @@ function beastFoo(beast: Object) { >hasLegs : (x: Beast) => x is Legged >beast : Winged - beast // beast is Legged + beast; // Winged & Legged >beast : Winged & Legged - - // ideally, beast would be Winged && Legged here... } else { - beast + beast; >beast : Object } @@ -302,9 +300,7 @@ function beastFoo(beast: Object) { >hasWings : (x: Beast) => x is Winged >beast : Legged - beast // beast is Winged + beast; // Legged & Winged >beast : Legged & Winged - - // ideally, beast would be Legged && Winged here... } } diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts index efde587e5e5d5..d0a999acd1c6f 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts @@ -71,14 +71,14 @@ function identifyBeast(beast: Beast) { // All winged beasts with legs if (hasWings(beast)) { - if (beast.legs === 4) { // ERROR TS2339: Property 'legs' does not exist on type 'Winged'. + if (beast.legs === 4) { log(`pegasus - 4 legs, wings`); } - else if (beast.legs === 2) { // ERROR TS2339... + else if (beast.legs === 2) { log(`bird - 2 legs, wings`); } else { - log(`unknown - ${beast.legs} legs, wings`); // ERROR TS2339... + log(`unknown - ${beast.legs} legs, wings`); } } @@ -101,15 +101,13 @@ function identifyBeast(beast: Beast) { function beastFoo(beast: Object) { if (hasWings(beast) && hasLegs(beast)) { - beast // beast is Legged - // ideally, beast would be Winged && Legged here... + beast; // Winged & Legged } else { - beast + beast; } if (hasLegs(beast) && hasWings(beast)) { - beast // beast is Winged - // ideally, beast would be Legged && Winged here... + beast; // Legged & Winged } } \ No newline at end of file From b1a749895a26bcb1115eb93e953f27100c33bdb5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 8 Jun 2016 18:39:07 -0700 Subject: [PATCH 5/5] Fix comment --- tests/baselines/reference/typeGuardIntersectionTypes.js | 2 +- tests/baselines/reference/typeGuardIntersectionTypes.symbols | 2 +- tests/baselines/reference/typeGuardIntersectionTypes.types | 2 +- .../expressions/typeGuards/typeGuardIntersectionTypes.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.js b/tests/baselines/reference/typeGuardIntersectionTypes.js index 6c46b982024f6..6de7d06e3232d 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.js +++ b/tests/baselines/reference/typeGuardIntersectionTypes.js @@ -50,7 +50,7 @@ function union(a: A): A & B | null { } } -// Repro from #9011 +// Repro from #9016 declare function log(s: string): void; diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.symbols b/tests/baselines/reference/typeGuardIntersectionTypes.symbols index 707fb95b339ec..ea8e903c76557 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.symbols +++ b/tests/baselines/reference/typeGuardIntersectionTypes.symbols @@ -117,7 +117,7 @@ function union(a: A): A & B | null { } } -// Repro from #9011 +// Repro from #9016 declare function log(s: string): void; >log : Symbol(log, Decl(typeGuardIntersectionTypes.ts, 49, 1)) diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.types b/tests/baselines/reference/typeGuardIntersectionTypes.types index 5ce768d4a5ee5..8be50453572b6 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.types +++ b/tests/baselines/reference/typeGuardIntersectionTypes.types @@ -133,7 +133,7 @@ function union(a: A): A & B | null { } } -// Repro from #9011 +// Repro from #9016 declare function log(s: string): void; >log : (s: string) => void diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts index d0a999acd1c6f..85c003787fd38 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts @@ -50,7 +50,7 @@ function union(a: A): A & B | null { } } -// Repro from #9011 +// Repro from #9016 declare function log(s: string): void;