Add fall-through test and correct comment about implied type

This commit is contained in:
Jack Williams
2018-05-23 01:03:04 +01:00
parent 0d79831ead
commit 9e43183884
5 changed files with 375 additions and 190 deletions

View File

@@ -13594,10 +13594,10 @@ namespace ts {
// }
//
// The implied type of the first clause number | string.
// The implied type of the second clause is string (but this doesn't get used).
// The implied type of the second clause is never, but this does not get just because it includes a default case.
// The implied type of the third clause is boolean (number has already be caught).
if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) {
let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts);
let impliedType = getTypeWithFacts(getUnionType((<string[]>clauseWitnesses).map(text => typeofTypesByName.get(text) || neverType)), switchFacts);
if (impliedType.flags & TypeFlags.Union) {
impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOfType(type) || type);
}
@@ -19027,17 +19027,20 @@ namespace ts {
if (hasDefault) {
// Value is not equal to any types after the active clause.
for (let i = end; i < witnesses.length; i++) {
facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject;
const witness = witnesses[i];
facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject;
}
// Remove inequalities for types that appear in the
// active clause because they appear before other
// types collected so far.
for (let i = start; i < end; i++) {
facts &= ~(typeofNEFacts.get(witnesses[i]) || 0);
const witness = witnesses[i];
facts &= ~((witness && typeofNEFacts.get(witness)) || 0);
}
// Add inequalities for types before the active clause unconditionally.
for (let i = 0; i < start; i++) {
facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject;
const witness = witnesses[i];
facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject;
}
}
// When in an active clause without default the set of
@@ -19045,12 +19048,14 @@ namespace ts {
else {
// Add equalities for all types in the active clause.
for (let i = start; i < end; i++) {
facts |= typeofEQFacts.get(witnesses[i]) || TypeFacts.TypeofEQHostObject;
const witness = witnesses[i];
facts |= (witness && typeofEQFacts.get(witness)) || TypeFacts.TypeofEQHostObject;
}
// Remove equalities for types that appear before the
// active clause.
for (let i = 0; i < start; i++) {
facts &= ~(typeofEQFacts.get(witnesses[i]) || 0);
const witness = witnesses[i];
facts &= ~((witness && typeofEQFacts.get(witness)) || 0);
}
}
return facts;

View File

@@ -35,6 +35,14 @@ function assertAll(x: Basic) {
return x;
}
function assertStringOrNumber(x: string | number) {
return x;
}
function assertBooleanOrObject(x: boolean | object) {
return x;
}
type Basic = number | boolean | string | symbol | object | Function | undefined;
function testUnion(x: Basic) {
@@ -186,6 +194,22 @@ function switchOrderingWithDefault(x: string | number | boolean) {
case 'number': return assertNever(x);
}
}
function fallThroughTest(x: string | number | boolean | object) {
switch (typeof x) {
case 'number':
assertNumber(x)
case 'string':
assertStringOrNumber(x)
break;
default:
assertObject(x);
case 'number':
case 'boolean':
assertBooleanOrObject(x);
break;
}
}
//// [narrowingByTypeofInSwitch.js]
@@ -216,6 +240,12 @@ function assertUndefined(x) {
function assertAll(x) {
return x;
}
function assertStringOrNumber(x) {
return x;
}
function assertBooleanOrObject(x) {
return x;
}
function testUnion(x) {
switch (typeof x) {
case 'number':
@@ -425,3 +455,18 @@ function switchOrderingWithDefault(x) {
case 'number': return assertNever(x);
}
}
function fallThroughTest(x) {
switch (typeof x) {
case 'number':
assertNumber(x);
case 'string':
assertStringOrNumber(x);
break;
default:
assertObject(x);
case 'number':
case 'boolean':
assertBooleanOrObject(x);
break;
}
}

View File

@@ -67,476 +67,525 @@ function assertUndefined(x: undefined) {
function assertAll(x: Basic) {
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19))
}
function assertStringOrNumber(x: string | number) {
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30))
}
function assertBooleanOrObject(x: boolean | object) {
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31))
}
type Basic = number | boolean | string | symbol | object | Function | undefined;
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
function testUnion(x: Basic) {
>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 36, 80))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 44, 80))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'object': assertObject(x); return;
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
}
assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
}
function testExtendsUnion<T extends Basic>(x: T) {
>testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 49, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26))
>testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 57, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 59, 26))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 59, 26))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'object': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
}
assertAll(x);
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
}
function testAny(x: any) {
>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 62, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 70, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'object': assertObject(x); return;
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
}
assertAll(x); // is any
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
}
function a1(x: string | object | undefined) {
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12))
}
function testUnionExplicitDefault(x: Basic) {
>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 79, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 87, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
default: a1(x); return;
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
}
}
function testUnionImplicitDefault(x: Basic) {
>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 89, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 97, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
}
return a1(x);
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
}
function testExtendsExplicitDefault<T extends Basic>(x: T) {
>testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 99, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36))
>testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 107, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 109, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 109, 36))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
default: assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
}
}
function testExtendsImplicitDefault<T extends Basic>(x: T) {
>testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 110, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36))
>testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 118, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 120, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 120, 36))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
}
return assertAll(x);
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
}
type L = (x: number) => string;
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 122, 10))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 130, 10))
type R = { x: string, y: number }
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
function exhaustiveChecks(x: number | string | L | R): string {
>exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 123, 33))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 131, 33))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
case 'number': return x.toString(2);
>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
case 'string': return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
case 'function': return x(42);
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
case 'object': return x.x;
>x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10))
>x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
}
}
function exhaustiveChecksGenerics<T extends L | R | number | string>(x: T): string {
>exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34))
>exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 140, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 142, 34))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 142, 34))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
case 'number': return x.toString(2);
>x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more)
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more)
case 'string': return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
case 'function': return (x as L)(42); // Can't narrow generic
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
case 'object': return (x as R).x; // Can't narrow generic
>(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10))
>(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
}
}
function multipleGeneric<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] {
>multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 141, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37))
>multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 149, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
case 'function': return [xy, xy(42)];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
case 'object': return [xy, xy.y];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
default: return assertNever(xy);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
}
}
function multipleGenericFuse<X extends L | number, Y extends R | number>(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] {
>multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 149, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50))
>multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 157, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
case 'function': return [xy, 1];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
case 'object': return [xy, 'two'];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
case 'number': return [xy]
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
}
}
function multipleGenericExhaustive<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] {
>multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 157, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47))
>multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 165, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
case 'object': return [xy, xy.y];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
case 'function': return [xy, xy(42)];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
}
}
function switchOrdering(x: string | number | boolean) {
>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 164, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 172, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
case 'string': return assertString(x);
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
case 'number': return assertNumber(x);
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
case 'boolean': return assertBoolean(x);
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
case 'number': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
}
}
function switchOrderingWithDefault(x: string | number | boolean) {
>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 173, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 181, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
function local(y: string | number | boolean) {
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 176, 19))
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 184, 19))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
}
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
case 'string':
case 'number':
default: return local(x)
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
case 'string': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
case 'number': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
}
}
function fallThroughTest(x: string | number | boolean | object) {
>fallThroughTest : Symbol(fallThroughTest, Decl(narrowingByTypeofInSwitch.ts, 194, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
case 'number':
assertNumber(x)
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
case 'string':
assertStringOrNumber(x)
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
break;
default:
assertObject(x);
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
case 'number':
case 'boolean':
assertBooleanOrObject(x);
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
break;
}
}

View File

@@ -73,6 +73,22 @@ function assertAll(x: Basic) {
>x : Basic
}
function assertStringOrNumber(x: string | number) {
>assertStringOrNumber : (x: string | number) => string | number
>x : string | number
return x;
>x : string | number
}
function assertBooleanOrObject(x: boolean | object) {
>assertBooleanOrObject : (x: boolean | object) => boolean | object
>x : boolean | object
return x;
>x : boolean | object
}
type Basic = number | boolean | string | symbol | object | Function | undefined;
>Basic : Basic
>Function : Function
@@ -693,3 +709,49 @@ function switchOrderingWithDefault(x: string | number | boolean) {
}
}
function fallThroughTest(x: string | number | boolean | object) {
>fallThroughTest : (x: string | number | boolean | object) => void
>x : string | number | boolean | object
switch (typeof x) {
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number | boolean | object
case 'number':
>'number' : "number"
assertNumber(x)
>assertNumber(x) : number
>assertNumber : (x: number) => number
>x : number
case 'string':
>'string' : "string"
assertStringOrNumber(x)
>assertStringOrNumber(x) : string | number
>assertStringOrNumber : (x: string | number) => string | number
>x : string | number
break;
default:
assertObject(x);
>assertObject(x) : object
>assertObject : (x: object) => object
>x : object
case 'number':
>'number' : "number"
case 'boolean':
>'boolean' : "boolean"
assertBooleanOrObject(x);
>assertBooleanOrObject(x) : boolean | object
>assertBooleanOrObject : (x: boolean | object) => boolean | object
>x : boolean | object
break;
}
}

View File

@@ -37,6 +37,14 @@ function assertAll(x: Basic) {
return x;
}
function assertStringOrNumber(x: string | number) {
return x;
}
function assertBooleanOrObject(x: boolean | object) {
return x;
}
type Basic = number | boolean | string | symbol | object | Function | undefined;
function testUnion(x: Basic) {
@@ -188,3 +196,19 @@ function switchOrderingWithDefault(x: string | number | boolean) {
case 'number': return assertNever(x);
}
}
function fallThroughTest(x: string | number | boolean | object) {
switch (typeof x) {
case 'number':
assertNumber(x)
case 'string':
assertStringOrNumber(x)
break;
default:
assertObject(x);
case 'number':
case 'boolean':
assertBooleanOrObject(x);
break;
}
}