Bring typeof switch inline with if (#27680)

- Narrow unknown
- Narrow union members (in addition to filtering)
This commit is contained in:
Jack W 2018-10-26 22:56:26 +01:00 committed by Wesley Wigham
parent 77d8e15905
commit abce9ae0be
5 changed files with 706 additions and 249 deletions

View file

@ -15441,6 +15441,32 @@ namespace ts {
return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]);
}
function getImpliedTypeFromTypeofCase(type: Type, text: string) {
switch (text) {
case "function":
return type.flags & TypeFlags.Any ? type : globalFunctionType;
case "object":
return type.flags & TypeFlags.Unknown ? getUnionType([nonPrimitiveType, nullType]) : type;
default:
return typeofTypesByName.get(text) || type;
}
}
function narrowTypeForTypeofSwitch(candidate: Type) {
return (type: Type) => {
if (isTypeSubtypeOf(candidate, type)) {
return candidate;
}
if (type.flags & TypeFlags.Instantiable) {
const constraint = getBaseConstraintOfType(type) || anyType;
if (isTypeSubtypeOf(candidate, constraint)) {
return getIntersectionType([type, candidate]);
}
}
return type;
};
}
function narrowBySwitchOnTypeOf(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): Type {
const switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement);
if (!switchWitnesses.length) {
@ -15458,7 +15484,7 @@ namespace ts {
// that we don't have to worry about undefined
// in the witness array.
const witnesses = <string[]>switchWitnesses.filter(witness => witness !== undefined);
// The adjust clause start and end after removing the `default` statement.
// The adjusted clause start and end after removing the `default` statement.
const fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart;
const fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd;
clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd);
@ -15468,6 +15494,9 @@ namespace ts {
clauseWitnesses = <string[]>switchWitnesses.slice(clauseStart, clauseEnd);
switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, <string[]>switchWitnesses, hasDefaultClause);
}
if (hasDefaultClause) {
return filterType(type, t => (getTypeFacts(t) & switchFacts) === switchFacts);
}
/*
The implied type is the raw type suggested by a
value being caught in this clause.
@ -15496,26 +15525,11 @@ namespace ts {
boolean. We know that number cannot be selected
because it is caught in the first clause.
*/
if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) {
let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts);
if (impliedType.flags & TypeFlags.Union) {
impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOfType(type) || type);
}
if (!(impliedType.flags & TypeFlags.Never)) {
if (isTypeSubtypeOf(impliedType, type)) {
return impliedType;
}
if (type.flags & TypeFlags.Instantiable) {
const constraint = getBaseConstraintOfType(type) || anyType;
if (isTypeSubtypeOf(impliedType, constraint)) {
return getIntersectionType([type, impliedType]);
}
}
}
let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => getImpliedTypeFromTypeofCase(type, text))), switchFacts);
if (impliedType.flags & TypeFlags.Union) {
impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOrType(type));
}
return hasDefaultClause ?
filterType(type, t => (getTypeFacts(t) & switchFacts) === switchFacts) :
getTypeWithFacts(type, switchFacts);
return getTypeWithFacts(mapType(type, narrowTypeForTypeofSwitch(impliedType)), switchFacts);
}
function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {

View file

@ -27,6 +27,10 @@ function assertObject(x: object) {
return x;
}
function assertObjectOrNull(x: object | null) {
return x;
}
function assertUndefined(x: undefined) {
return x;
}
@ -35,11 +39,11 @@ function assertAll(x: Basic) {
return x;
}
function assertStringOrNumber(x: string | number) {
function assertStringOrNumber(x: string | number) {
return x;
}
function assertBooleanOrObject(x: boolean | object) {
function assertBooleanOrObject(x: boolean | object) {
return x;
}
@ -210,6 +214,41 @@ function fallThroughTest(x: string | number | boolean | object) {
break;
}
}
function unknownNarrowing(x: unknown) {
switch (typeof x) {
case 'number': assertNumber(x); return;
case 'boolean': assertBoolean(x); return;
case 'function': assertFunction(x); return;
case 'symbol': assertSymbol(x); return;
case 'object': assertObjectOrNull(x); return;
case 'string': assertString(x); return;
case 'undefined': assertUndefined(x); return;
}
}
function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) {
function assertKeyofS(k1: keyof S) { }
switch (typeof k) {
case 'number': assertNumber(k); assertKeyofS(k); return;
case 'symbol': assertSymbol(k); assertKeyofS(k); return;
case 'string': assertString(k); assertKeyofS(k); return;
}
}
function narrowingNarrows(x: {} | undefined) {
switch (typeof x) {
case 'number': assertNumber(x); return;
case 'boolean': assertBoolean(x); return;
case 'function': assertFunction(x); return;
case 'symbol': assertSymbol(x); return;
case 'object': const _: {} = x; return;
case 'string': assertString(x); return;
case 'undefined': assertUndefined(x); return;
case 'number': assertNever(x); return;
default: const _y: {} = x; return;
}
}
//// [narrowingByTypeofInSwitch.js]
@ -234,6 +273,9 @@ function assertFunction(x) {
function assertObject(x) {
return x;
}
function assertObjectOrNull(x) {
return x;
}
function assertUndefined(x) {
return x;
}
@ -470,3 +512,76 @@ function fallThroughTest(x) {
break;
}
}
function unknownNarrowing(x) {
switch (typeof x) {
case 'number':
assertNumber(x);
return;
case 'boolean':
assertBoolean(x);
return;
case 'function':
assertFunction(x);
return;
case 'symbol':
assertSymbol(x);
return;
case 'object':
assertObjectOrNull(x);
return;
case 'string':
assertString(x);
return;
case 'undefined':
assertUndefined(x);
return;
}
}
function keyofNarrowing(k) {
function assertKeyofS(k1) { }
switch (typeof k) {
case 'number':
assertNumber(k);
assertKeyofS(k);
return;
case 'symbol':
assertSymbol(k);
assertKeyofS(k);
return;
case 'string':
assertString(k);
assertKeyofS(k);
return;
}
}
function narrowingNarrows(x) {
switch (typeof x) {
case 'number':
assertNumber(x);
return;
case 'boolean':
assertBoolean(x);
return;
case 'function':
assertFunction(x);
return;
case 'symbol':
assertSymbol(x);
return;
case 'object':
var _ = x;
return;
case 'string':
assertString(x);
return;
case 'undefined':
assertUndefined(x);
return;
case 'number':
assertNever(x);
return;
default:
var _y = x;
return;
}
}

View file

@ -56,536 +56,662 @@ function assertObject(x: object) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 24, 22))
}
function assertUndefined(x: undefined) {
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 25))
function assertObjectOrNull(x: object | null) {
>assertObjectOrNull : Symbol(assertObjectOrNull, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 28))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 25))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 28))
}
function assertUndefined(x: undefined) {
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 25))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 25))
}
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, 42, 1))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 19))
}
function assertStringOrNumber(x: string | number) {
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30))
function assertStringOrNumber(x: string | number) {
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 30))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 30))
}
function assertBooleanOrObject(x: boolean | object) {
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31))
function assertBooleanOrObject(x: boolean | object) {
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 44, 31))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 44, 31))
}
type Basic = number | boolean | string | symbol | object | Function | undefined;
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
function testUnion(x: Basic) {
>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 44, 80))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 48, 80))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'object': assertObject(x); return;
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
}
assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 50, 19))
}
function testExtendsUnion<T extends Basic>(x: T) {
>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))
>testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 61, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 63, 26))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 63, 26))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'object': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
}
assertAll(x);
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 63, 43))
}
function testAny(x: any) {
>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 70, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 74, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'object': assertObject(x); return;
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
}
assertAll(x); // is any
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 76, 17))
}
function a1(x: string | object | undefined) {
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 87, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 12))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 12))
}
function testUnionExplicitDefault(x: Basic) {
>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 87, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 91, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
default: a1(x); return;
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 87, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 93, 34))
}
}
function testUnionImplicitDefault(x: Basic) {
>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 97, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 101, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
}
return a1(x);
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34))
>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 87, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 103, 34))
}
function testExtendsExplicitDefault<T extends Basic>(x: T) {
>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))
>testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 111, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 113, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 113, 36))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
default: assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 113, 53))
}
}
function testExtendsImplicitDefault<T extends Basic>(x: T) {
>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))
>testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 122, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 124, 36))
>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 124, 36))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
case 'function': assertAll(x); return;
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
}
return assertAll(x);
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53))
>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 124, 53))
}
type L = (x: number) => string;
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 130, 10))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 10))
type R = { x: string, y: number }
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 135, 10))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 135, 21))
function exhaustiveChecks(x: number | string | L | R): string {
>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))
>exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 135, 33))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
case 'number': return x.toString(2);
>x.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
case 'string': return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
case 'function': return x(42);
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
case 'object': return x.x;
>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))
>x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 135, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 137, 26))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 135, 10))
}
}
function exhaustiveChecksGenerics<T extends L | R | number | string>(x: T): string {
>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))
>exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 144, 1))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 146, 34))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 146, 34))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
case 'number': return x.toString(2);
>x.toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
>toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
case 'string': return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
case 'function': return (x as L)(42); // Can't narrow generic
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
case 'object': return (x as R).x; // Can't narrow generic
>(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))
>(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 135, 10))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 135, 10))
}
}
function multipleGeneric<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] {
>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))
>multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 153, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 155, 25))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 155, 37))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 155, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 155, 37))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 155, 25))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 155, 37))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
case 'function': return [xy, xy(42)];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
case 'object': return [xy, xy.y];
>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))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 135, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 51))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 135, 21))
default: return assertNever(xy);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 155, 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, 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))
>multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 161, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 163, 29))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 163, 50))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 163, 73))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 163, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 163, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 163, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 163, 50))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 163, 29))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 163, 50))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 163, 73))
case 'function': return [xy, 1];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 163, 73))
case 'object': return [xy, 'two'];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 163, 73))
case 'number': return [xy]
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 163, 73))
}
}
function multipleGenericExhaustive<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] {
>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))
>multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 169, 1))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 171, 35))
>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 171, 47))
>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 171, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 171, 47))
>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 171, 35))
>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 171, 47))
switch (typeof xy) {
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
case 'object': return [xy, xy.y];
>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))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 135, 21))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 135, 21))
case 'function': return [xy, xy(42)];
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 171, 61))
}
}
function switchOrdering(x: string | number | boolean) {
>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 172, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 176, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
case 'string': return assertString(x);
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
case 'number': return assertNumber(x);
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
case 'boolean': return assertBoolean(x);
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
case 'number': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 178, 24))
}
}
function switchOrderingWithDefault(x: string | number | boolean) {
>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 181, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 185, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
function local(y: string | number | boolean) {
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 184, 19))
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 187, 66))
>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 188, 19))
return x;
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
}
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
case 'string':
case 'number':
default: return local(x)
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 187, 66))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
case 'string': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
case 'number': return assertNever(x);
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 187, 35))
}
}
function fallThroughTest(x: string | number | boolean | object) {
>fallThroughTest : Symbol(fallThroughTest, Decl(narrowingByTypeofInSwitch.ts, 194, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>fallThroughTest : Symbol(fallThroughTest, Decl(narrowingByTypeofInSwitch.ts, 198, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
case 'number':
assertNumber(x)
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
case 'string':
assertStringOrNumber(x)
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
break;
default:
assertObject(x);
>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
case 'number':
case 'boolean':
assertBooleanOrObject(x);
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25))
>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 42, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 200, 25))
break;
}
}
function unknownNarrowing(x: unknown) {
>unknownNarrowing : Symbol(unknownNarrowing, Decl(narrowingByTypeofInSwitch.ts, 214, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'object': assertObjectOrNull(x); return;
>assertObjectOrNull : Symbol(assertObjectOrNull, Decl(narrowingByTypeofInSwitch.ts, 26, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 216, 26))
}
}
function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) {
>keyofNarrowing : Symbol(keyofNarrowing, Decl(narrowingByTypeofInSwitch.ts, 226, 1))
>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 228, 24))
>K : Symbol(K, Decl(narrowingByTypeofInSwitch.ts, 228, 37))
>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 228, 24))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 228, 24))
function assertKeyofS(k1: keyof S) { }
>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 228, 75))
>k1 : Symbol(k1, Decl(narrowingByTypeofInSwitch.ts, 229, 26))
>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 228, 24))
switch (typeof k) {
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
case 'number': assertNumber(k); assertKeyofS(k); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 228, 75))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
case 'symbol': assertSymbol(k); assertKeyofS(k); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 228, 75))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
case 'string': assertString(k); assertKeyofS(k); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 228, 75))
>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 228, 62))
}
}
function narrowingNarrows(x: {} | undefined) {
>narrowingNarrows : Symbol(narrowingNarrows, Decl(narrowingByTypeofInSwitch.ts, 235, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
switch (typeof x) {
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'number': assertNumber(x); return;
>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'boolean': assertBoolean(x); return;
>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'function': assertFunction(x); return;
>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'symbol': assertSymbol(x); return;
>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'object': const _: {} = x; return;
>_ : Symbol(_, Decl(narrowingByTypeofInSwitch.ts, 243, 28))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'string': assertString(x); return;
>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'undefined': assertUndefined(x); return;
>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
case 'number': assertNever(x); return;
>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
default: const _y: {} = x; return;
>_y : Symbol(_y, Decl(narrowingByTypeofInSwitch.ts, 247, 22))
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 237, 26))
}
}

View file

@ -55,6 +55,15 @@ function assertObject(x: object) {
>x : object
}
function assertObjectOrNull(x: object | null) {
>assertObjectOrNull : (x: object | null) => object | null
>x : object | null
>null : null
return x;
>x : object | null
}
function assertUndefined(x: undefined) {
>assertUndefined : (x: undefined) => undefined
>x : undefined
@ -71,7 +80,7 @@ function assertAll(x: Basic) {
>x : Basic
}
function assertStringOrNumber(x: string | number) {
function assertStringOrNumber(x: string | number) {
>assertStringOrNumber : (x: string | number) => string | number
>x : string | number
@ -79,7 +88,7 @@ function assertStringOrNumber(x: string | number) {
>x : string | number
}
function assertBooleanOrObject(x: boolean | object) {
function assertBooleanOrObject(x: boolean | object) {
>assertBooleanOrObject : (x: boolean | object) => boolean | object
>x : boolean | object
@ -170,7 +179,7 @@ function testExtendsUnion<T extends Basic>(x: T) {
>'function' : "function"
>assertAll(x) : Basic
>assertAll : (x: Basic) => Basic
>x : T
>x : T & Function
case 'symbol': assertSymbol(x); return;
>'symbol' : "symbol"
@ -367,7 +376,7 @@ function testExtendsExplicitDefault<T extends Basic>(x: T) {
>'function' : "function"
>assertAll(x) : Basic
>assertAll : (x: Basic) => Basic
>x : T
>x : T & Function
case 'symbol': assertSymbol(x); return;
>'symbol' : "symbol"
@ -407,7 +416,7 @@ function testExtendsImplicitDefault<T extends Basic>(x: T) {
>'function' : "function"
>assertAll(x) : Basic
>assertAll : (x: Basic) => Basic
>x : T
>x : T & Function
case 'symbol': assertSymbol(x); return;
>'symbol' : "symbol"
@ -555,8 +564,8 @@ function multipleGenericFuse<X extends L | number, Y extends R | number>(xy: X |
case 'number': return [xy]
>'number' : "number"
>[xy] : [X | Y]
>xy : X | Y
>[xy] : [(X & number) | (Y & number)]
>xy : (X & number) | (Y & number)
}
}
@ -706,3 +715,157 @@ function fallThroughTest(x: string | number | boolean | object) {
}
}
function unknownNarrowing(x: unknown) {
>unknownNarrowing : (x: unknown) => void
>x : unknown
switch (typeof x) {
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : unknown
case 'number': assertNumber(x); return;
>'number' : "number"
>assertNumber(x) : number
>assertNumber : (x: number) => number
>x : number
case 'boolean': assertBoolean(x); return;
>'boolean' : "boolean"
>assertBoolean(x) : boolean
>assertBoolean : (x: boolean) => boolean
>x : boolean
case 'function': assertFunction(x); return;
>'function' : "function"
>assertFunction(x) : Function
>assertFunction : (x: Function) => Function
>x : Function
case 'symbol': assertSymbol(x); return;
>'symbol' : "symbol"
>assertSymbol(x) : symbol
>assertSymbol : (x: symbol) => symbol
>x : symbol
case 'object': assertObjectOrNull(x); return;
>'object' : "object"
>assertObjectOrNull(x) : object | null
>assertObjectOrNull : (x: object | null) => object | null
>x : object | null
case 'string': assertString(x); return;
>'string' : "string"
>assertString(x) : string
>assertString : (x: string) => string
>x : string
case 'undefined': assertUndefined(x); return;
>'undefined' : "undefined"
>assertUndefined(x) : undefined
>assertUndefined : (x: undefined) => undefined
>x : undefined
}
}
function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) {
>keyofNarrowing : <S extends { [K in keyof S]: string; }>(k: keyof S) => void
>k : keyof S
function assertKeyofS(k1: keyof S) { }
>assertKeyofS : (k1: keyof S) => void
>k1 : keyof S
switch (typeof k) {
>typeof k : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>k : keyof S
case 'number': assertNumber(k); assertKeyofS(k); return;
>'number' : "number"
>assertNumber(k) : number
>assertNumber : (x: number) => number
>k : keyof S & number
>assertKeyofS(k) : void
>assertKeyofS : (k1: keyof S) => void
>k : keyof S & number
case 'symbol': assertSymbol(k); assertKeyofS(k); return;
>'symbol' : "symbol"
>assertSymbol(k) : symbol
>assertSymbol : (x: symbol) => symbol
>k : keyof S & symbol
>assertKeyofS(k) : void
>assertKeyofS : (k1: keyof S) => void
>k : keyof S & symbol
case 'string': assertString(k); assertKeyofS(k); return;
>'string' : "string"
>assertString(k) : string
>assertString : (x: string) => string
>k : keyof S & string
>assertKeyofS(k) : void
>assertKeyofS : (k1: keyof S) => void
>k : keyof S & string
}
}
function narrowingNarrows(x: {} | undefined) {
>narrowingNarrows : (x: {} | undefined) => void
>x : {} | undefined
switch (typeof x) {
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : {} | undefined
case 'number': assertNumber(x); return;
>'number' : "number"
>assertNumber(x) : number
>assertNumber : (x: number) => number
>x : number
case 'boolean': assertBoolean(x); return;
>'boolean' : "boolean"
>assertBoolean(x) : boolean
>assertBoolean : (x: boolean) => boolean
>x : boolean
case 'function': assertFunction(x); return;
>'function' : "function"
>assertFunction(x) : Function
>assertFunction : (x: Function) => Function
>x : Function
case 'symbol': assertSymbol(x); return;
>'symbol' : "symbol"
>assertSymbol(x) : symbol
>assertSymbol : (x: symbol) => symbol
>x : symbol
case 'object': const _: {} = x; return;
>'object' : "object"
>_ : {}
>x : {}
case 'string': assertString(x); return;
>'string' : "string"
>assertString(x) : string
>assertString : (x: string) => string
>x : string
case 'undefined': assertUndefined(x); return;
>'undefined' : "undefined"
>assertUndefined(x) : undefined
>assertUndefined : (x: undefined) => undefined
>x : undefined
case 'number': assertNever(x); return;
>'number' : "number"
>assertNever(x) : never
>assertNever : (x: never) => never
>x : never
default: const _y: {} = x; return;
>_y : {}
>x : {}
}
}

View file

@ -29,6 +29,10 @@ function assertObject(x: object) {
return x;
}
function assertObjectOrNull(x: object | null) {
return x;
}
function assertUndefined(x: undefined) {
return x;
}
@ -37,11 +41,11 @@ function assertAll(x: Basic) {
return x;
}
function assertStringOrNumber(x: string | number) {
function assertStringOrNumber(x: string | number) {
return x;
}
function assertBooleanOrObject(x: boolean | object) {
function assertBooleanOrObject(x: boolean | object) {
return x;
}
@ -212,3 +216,38 @@ function fallThroughTest(x: string | number | boolean | object) {
break;
}
}
function unknownNarrowing(x: unknown) {
switch (typeof x) {
case 'number': assertNumber(x); return;
case 'boolean': assertBoolean(x); return;
case 'function': assertFunction(x); return;
case 'symbol': assertSymbol(x); return;
case 'object': assertObjectOrNull(x); return;
case 'string': assertString(x); return;
case 'undefined': assertUndefined(x); return;
}
}
function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) {
function assertKeyofS(k1: keyof S) { }
switch (typeof k) {
case 'number': assertNumber(k); assertKeyofS(k); return;
case 'symbol': assertSymbol(k); assertKeyofS(k); return;
case 'string': assertString(k); assertKeyofS(k); return;
}
}
function narrowingNarrows(x: {} | undefined) {
switch (typeof x) {
case 'number': assertNumber(x); return;
case 'boolean': assertBoolean(x); return;
case 'function': assertFunction(x); return;
case 'symbol': assertSymbol(x); return;
case 'object': const _: {} = x; return;
case 'string': assertString(x); return;
case 'undefined': assertUndefined(x); return;
case 'number': assertNever(x); return;
default: const _y: {} = x; return;
}
}