1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/compiler/narrowingByTypeofInSwitch.ts === 20declare function AssertType(value:any, type:string):void; 21function assertNever(x: never) { 22AssertType(x, "never"); 23 return x; 24} 25 26function assertNumber(x: number) { 27AssertType(x, "number"); 28 return x; 29} 30 31function assertBoolean(x: boolean) { 32AssertType(x, "boolean"); 33 return x; 34} 35 36function assertString(x: string) { 37AssertType(x, "string"); 38 return x; 39} 40 41function assertSymbol(x: symbol) { 42AssertType(x, "symbol"); 43 return x; 44} 45 46function assertFunction(x: Function) { 47AssertType(x, "Function"); 48 return x; 49} 50 51function assertObject(x: object) { 52AssertType(x, "object"); 53 return x; 54} 55 56function assertObjectOrNull(x: object | null) { 57AssertType(x, "union"); 58 return x; 59} 60 61function assertUndefined(x: undefined) { 62AssertType(x, "undefined"); 63 return x; 64} 65 66function assertAll(x: Basic) { 67AssertType(x, "Basic"); 68 return x; 69} 70 71function assertStringOrNumber(x: string | number) { 72AssertType(x, "union"); 73 return x; 74} 75 76function assertBooleanOrObject(x: boolean | object) { 77AssertType(x, "union"); 78 return x; 79} 80 81type Basic = number | boolean | string | symbol | object | Function | undefined; 82 83function testUnion(x: Basic) { 84 switch (typeof x) { 85AssertType(typeof x, "union"); 86AssertType(x, "Basic"); 87 88 case 'number': assertNumber(x); 89AssertType('number', "string"); 90AssertType(assertNumber(x), "number"); 91AssertType(assertNumber, "(number) => number"); 92AssertType(x, "number"); 93return; 94 95 case 'boolean': assertBoolean(x); 96AssertType('boolean', "string"); 97AssertType(assertBoolean(x), "boolean"); 98AssertType(assertBoolean, "(boolean) => boolean"); 99AssertType(x, "boolean"); 100return; 101 102 case 'function': assertFunction(x); 103AssertType('function', "string"); 104AssertType(assertFunction(x), "Function"); 105AssertType(assertFunction, "(Function) => Function"); 106AssertType(x, "Function"); 107return; 108 109 case 'symbol': assertSymbol(x); 110AssertType('symbol', "string"); 111AssertType(assertSymbol(x), "symbol"); 112AssertType(assertSymbol, "(symbol) => symbol"); 113AssertType(x, "symbol"); 114return; 115 116 case 'object': assertObject(x); 117AssertType('object', "string"); 118AssertType(assertObject(x), "object"); 119AssertType(assertObject, "(object) => object"); 120AssertType(x, "object"); 121return; 122 123 case 'string': assertString(x); 124AssertType('string', "string"); 125AssertType(assertString(x), "string"); 126AssertType(assertString, "(string) => string"); 127AssertType(x, "string"); 128return; 129 130 case 'undefined': assertUndefined(x); 131AssertType('undefined', "string"); 132AssertType(assertUndefined(x), "undefined"); 133AssertType(assertUndefined, "(undefined) => undefined"); 134AssertType(x, "undefined"); 135return; 136 } 137 assertNever(x); 138AssertType(assertNever(x), "never"); 139AssertType(assertNever, "(never) => never"); 140AssertType(x, "never"); 141} 142 143function testExtendsUnion<T extends Basic>(x: T) { 144 switch (typeof x) { 145AssertType(typeof x, "union"); 146AssertType(x, "T"); 147 148 case 'number': assertNumber(x); 149AssertType('number', "string"); 150AssertType(assertNumber(x), "number"); 151AssertType(assertNumber, "(number) => number"); 152AssertType(x, "number"); 153return; 154 155 case 'boolean': assertBoolean(x); 156AssertType('boolean', "string"); 157AssertType(assertBoolean(x), "boolean"); 158AssertType(assertBoolean, "(boolean) => boolean"); 159AssertType(x, "boolean"); 160return; 161 162 case 'function': assertAll(x); 163AssertType('function', "string"); 164AssertType(assertAll(x), "Basic"); 165AssertType(assertAll, "(Basic) => Basic"); 166AssertType(x, "Function"); 167return; 168 169 case 'symbol': assertSymbol(x); 170AssertType('symbol', "string"); 171AssertType(assertSymbol(x), "symbol"); 172AssertType(assertSymbol, "(symbol) => symbol"); 173AssertType(x, "symbol"); 174return; 175 176 case 'object': assertAll(x); 177AssertType('object', "string"); 178AssertType(assertAll(x), "Basic"); 179AssertType(assertAll, "(Basic) => Basic"); 180AssertType(x, "object"); 181return; 182 183 case 'string': assertString(x); 184AssertType('string', "string"); 185AssertType(assertString(x), "string"); 186AssertType(assertString, "(string) => string"); 187AssertType(x, "string"); 188return; 189 190 case 'undefined': assertUndefined(x); 191AssertType('undefined', "string"); 192AssertType(assertUndefined(x), "undefined"); 193AssertType(assertUndefined, "(undefined) => undefined"); 194AssertType(x, "undefined"); 195return; 196 } 197 assertAll(x); 198AssertType(assertAll(x), "Basic"); 199AssertType(assertAll, "(Basic) => Basic"); 200AssertType(x, "never"); 201} 202 203function testAny(x: any) { 204 switch (typeof x) { 205AssertType(typeof x, "union"); 206AssertType(x, "any"); 207 208 case 'number': assertNumber(x); 209AssertType('number', "string"); 210AssertType(assertNumber(x), "number"); 211AssertType(assertNumber, "(number) => number"); 212AssertType(x, "number"); 213return; 214 215 case 'boolean': assertBoolean(x); 216AssertType('boolean', "string"); 217AssertType(assertBoolean(x), "boolean"); 218AssertType(assertBoolean, "(boolean) => boolean"); 219AssertType(x, "boolean"); 220return; 221 222 case 'function': assertFunction(x); 223AssertType('function', "string"); 224AssertType(assertFunction(x), "Function"); 225AssertType(assertFunction, "(Function) => Function"); 226AssertType(x, "any"); 227return; 228 229 case 'symbol': assertSymbol(x); 230AssertType('symbol', "string"); 231AssertType(assertSymbol(x), "symbol"); 232AssertType(assertSymbol, "(symbol) => symbol"); 233AssertType(x, "symbol"); 234return; 235 236 case 'object': assertObject(x); 237AssertType('object', "string"); 238AssertType(assertObject(x), "object"); 239AssertType(assertObject, "(object) => object"); 240AssertType(x, "any"); 241return; 242 243 case 'string': assertString(x); 244AssertType('string', "string"); 245AssertType(assertString(x), "string"); 246AssertType(assertString, "(string) => string"); 247AssertType(x, "string"); 248return; 249 250 case 'undefined': assertUndefined(x); 251AssertType('undefined', "string"); 252AssertType(assertUndefined(x), "undefined"); 253AssertType(assertUndefined, "(undefined) => undefined"); 254AssertType(x, "undefined"); 255return; 256 } 257 assertAll(x); // is any 258AssertType(assertAll(x), "Basic"); 259AssertType(assertAll, "(Basic) => Basic"); 260AssertType(x, "any"); 261} 262 263function a1(x: string | object | undefined) { 264AssertType(x, "union"); 265 return x; 266} 267 268function testUnionExplicitDefault(x: Basic) { 269 switch (typeof x) { 270AssertType(typeof x, "union"); 271AssertType(x, "Basic"); 272 273 case 'number': assertNumber(x); 274AssertType('number', "string"); 275AssertType(assertNumber(x), "number"); 276AssertType(assertNumber, "(number) => number"); 277AssertType(x, "number"); 278return; 279 280 case 'boolean': assertBoolean(x); 281AssertType('boolean', "string"); 282AssertType(assertBoolean(x), "boolean"); 283AssertType(assertBoolean, "(boolean) => boolean"); 284AssertType(x, "boolean"); 285return; 286 287 case 'function': assertFunction(x); 288AssertType('function', "string"); 289AssertType(assertFunction(x), "Function"); 290AssertType(assertFunction, "(Function) => Function"); 291AssertType(x, "Function"); 292return; 293 294 case 'symbol': assertSymbol(x); 295AssertType('symbol', "string"); 296AssertType(assertSymbol(x), "symbol"); 297AssertType(assertSymbol, "(symbol) => symbol"); 298AssertType(x, "symbol"); 299return; 300 301 default: a1(x); 302AssertType(a1(x), "union"); 303AssertType(a1, "(union) => union"); 304AssertType(x, "union"); 305return; 306 } 307} 308 309function testUnionImplicitDefault(x: Basic) { 310 switch (typeof x) { 311AssertType(typeof x, "union"); 312AssertType(x, "Basic"); 313 314 case 'number': assertNumber(x); 315AssertType('number', "string"); 316AssertType(assertNumber(x), "number"); 317AssertType(assertNumber, "(number) => number"); 318AssertType(x, "number"); 319return; 320 321 case 'boolean': assertBoolean(x); 322AssertType('boolean', "string"); 323AssertType(assertBoolean(x), "boolean"); 324AssertType(assertBoolean, "(boolean) => boolean"); 325AssertType(x, "boolean"); 326return; 327 328 case 'function': assertFunction(x); 329AssertType('function', "string"); 330AssertType(assertFunction(x), "Function"); 331AssertType(assertFunction, "(Function) => Function"); 332AssertType(x, "Function"); 333return; 334 335 case 'symbol': assertSymbol(x); 336AssertType('symbol', "string"); 337AssertType(assertSymbol(x), "symbol"); 338AssertType(assertSymbol, "(symbol) => symbol"); 339AssertType(x, "symbol"); 340return; 341 } 342AssertType(a1(x), "union"); 343AssertType(a1, "(union) => union"); 344AssertType(x, "union"); 345 return a1(x); 346} 347 348function testExtendsExplicitDefault<T extends Basic>(x: T) { 349 switch (typeof x) { 350AssertType(typeof x, "union"); 351AssertType(x, "T"); 352 353 case 'number': assertNumber(x); 354AssertType('number', "string"); 355AssertType(assertNumber(x), "number"); 356AssertType(assertNumber, "(number) => number"); 357AssertType(x, "number"); 358return; 359 360 case 'boolean': assertBoolean(x); 361AssertType('boolean', "string"); 362AssertType(assertBoolean(x), "boolean"); 363AssertType(assertBoolean, "(boolean) => boolean"); 364AssertType(x, "boolean"); 365return; 366 367 case 'function': assertAll(x); 368AssertType('function', "string"); 369AssertType(assertAll(x), "Basic"); 370AssertType(assertAll, "(Basic) => Basic"); 371AssertType(x, "Function"); 372return; 373 374 case 'symbol': assertSymbol(x); 375AssertType('symbol', "string"); 376AssertType(assertSymbol(x), "symbol"); 377AssertType(assertSymbol, "(symbol) => symbol"); 378AssertType(x, "symbol"); 379return; 380 381 default: assertAll(x); 382AssertType(assertAll(x), "Basic"); 383AssertType(assertAll, "(Basic) => Basic"); 384AssertType(x, "union"); 385return; 386 387 } 388} 389 390function testExtendsImplicitDefault<T extends Basic>(x: T) { 391 switch (typeof x) { 392AssertType(typeof x, "union"); 393AssertType(x, "T"); 394 395 case 'number': assertNumber(x); 396AssertType('number', "string"); 397AssertType(assertNumber(x), "number"); 398AssertType(assertNumber, "(number) => number"); 399AssertType(x, "number"); 400return; 401 402 case 'boolean': assertBoolean(x); 403AssertType('boolean', "string"); 404AssertType(assertBoolean(x), "boolean"); 405AssertType(assertBoolean, "(boolean) => boolean"); 406AssertType(x, "boolean"); 407return; 408 409 case 'function': assertAll(x); 410AssertType('function', "string"); 411AssertType(assertAll(x), "Basic"); 412AssertType(assertAll, "(Basic) => Basic"); 413AssertType(x, "Function"); 414return; 415 416 case 'symbol': assertSymbol(x); 417AssertType('symbol', "string"); 418AssertType(assertSymbol(x), "symbol"); 419AssertType(assertSymbol, "(symbol) => symbol"); 420AssertType(x, "symbol"); 421return; 422 } 423AssertType(assertAll(x), "Basic"); 424AssertType(assertAll, "(Basic) => Basic"); 425AssertType(x, "union"); 426 return assertAll(x); 427} 428 429type L = (x: number) => string; 430type R = { x: string, y: number } 431 432function exhaustiveChecks(x: number | string | L | R): string { 433 switch (typeof x) { 434AssertType(typeof x, "union"); 435AssertType(x, "union"); 436 437 case 'number': 438AssertType('number', "string"); 439AssertType(x.toString(2), "string"); 440AssertType(x.toString, "(?union) => string"); 441AssertType(2, "int"); 442return x.toString(2); 443 444 case 'string': 445AssertType('string', "string"); 446AssertType(x, "string"); 447return x; 448 449 case 'function': 450AssertType('function', "string"); 451AssertType(x(42), "string"); 452AssertType(x, "L"); 453AssertType(42, "int"); 454return x(42); 455 456 case 'object': 457AssertType('object', "string"); 458AssertType(x.x, "string"); 459return x.x; 460 } 461} 462 463function exhaustiveChecksGenerics<T extends L | R | number | string>(x: T): string { 464 switch (typeof x) { 465AssertType(typeof x, "union"); 466AssertType(x, "T"); 467 468 case 'number': 469AssertType('number', "string"); 470AssertType(x.toString(2), "string"); 471AssertType(x.toString, "(?union) => string"); 472AssertType(2, "int"); 473return x.toString(2); 474 475 case 'string': 476AssertType('string', "string"); 477AssertType(x, "string"); 478return x; 479 480 case 'function': 481AssertType('function', "string"); 482AssertType((x as L)(42), "string"); 483AssertType((x as L), "L"); 484AssertType(x as L, "L"); 485AssertType(x, "L"); 486AssertType(42, "int"); 487return (x as L)(42); // Can't narrow generic 488 489 case 'object': 490AssertType('object', "string"); 491AssertType((x as R).x, "string"); 492AssertType((x as R), "R"); 493AssertType(x as R, "R"); 494AssertType(x, "R"); 495return (x as R).x; // Can't narrow generic 496 } 497} 498 499function multipleGeneric<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] { 500 switch (typeof xy) { 501AssertType(typeof xy, "union"); 502AssertType(xy, "union"); 503 504 case 'function': 505AssertType('function', "string"); 506AssertType([xy, xy(42)], "[X, string]"); 507AssertType(xy, "X"); 508AssertType(xy(42), "string"); 509AssertType(xy, "X"); 510AssertType(42, "int"); 511return [xy, xy(42)]; 512 513 case 'object': 514AssertType('object', "string"); 515AssertType([xy, xy.y], "[Y, number]"); 516AssertType(xy, "Y"); 517AssertType(xy.y, "number"); 518return [xy, xy.y]; 519 520 default: 521AssertType(assertNever(xy), "never"); 522AssertType(assertNever, "(never) => never"); 523AssertType(xy, "never"); 524return assertNever(xy); 525 } 526} 527 528function multipleGenericFuse<X extends L | number, Y extends R | number>(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { 529 switch (typeof xy) { 530AssertType(typeof xy, "union"); 531AssertType(xy, "union"); 532 533 case 'function': 534AssertType('function', "string"); 535AssertType([xy, 1], "[X & Function, 1]"); 536AssertType(xy, "X & Function"); 537AssertType(1, "int"); 538return [xy, 1]; 539 540 case 'object': 541AssertType('object', "string"); 542AssertType([xy, 'two'], "[Y & object, string]"); 543AssertType(xy, "Y & object"); 544AssertType('two', "string"); 545return [xy, 'two']; 546 547 case 'number': 548AssertType('number', "string"); 549AssertType([xy], "[union]"); 550AssertType(xy, "union"); 551return [xy] 552 } 553} 554 555function multipleGenericExhaustive<X extends L, Y extends R>(xy: X | Y): [X, string] | [Y, number] { 556 switch (typeof xy) { 557AssertType(typeof xy, "union"); 558AssertType(xy, "union"); 559 560 case 'object': 561AssertType('object', "string"); 562AssertType([xy, xy.y], "[Y, number]"); 563AssertType(xy, "Y"); 564AssertType(xy.y, "number"); 565return [xy, xy.y]; 566 567 case 'function': 568AssertType('function', "string"); 569AssertType([xy, xy(42)], "[X, string]"); 570AssertType(xy, "X"); 571AssertType(xy(42), "string"); 572AssertType(xy, "X"); 573AssertType(42, "int"); 574return [xy, xy(42)]; 575 } 576} 577 578function switchOrdering(x: string | number | boolean) { 579 switch (typeof x) { 580AssertType(typeof x, "union"); 581AssertType(x, "union"); 582 583 case 'string': 584AssertType('string', "string"); 585AssertType(assertString(x), "string"); 586AssertType(assertString, "(string) => string"); 587AssertType(x, "string"); 588return assertString(x); 589 590 case 'number': 591AssertType('number', "string"); 592AssertType(assertNumber(x), "number"); 593AssertType(assertNumber, "(number) => number"); 594AssertType(x, "number"); 595return assertNumber(x); 596 597 case 'boolean': 598AssertType('boolean', "string"); 599AssertType(assertBoolean(x), "boolean"); 600AssertType(assertBoolean, "(boolean) => boolean"); 601AssertType(x, "boolean"); 602return assertBoolean(x); 603 604 case 'number': 605AssertType('number', "string"); 606AssertType(assertNever(x), "never"); 607AssertType(assertNever, "(never) => never"); 608AssertType(x, "never"); 609return assertNever(x); 610 } 611} 612 613function switchOrderingWithDefault(x: string | number | boolean) { 614 function local(y: string | number | boolean) { 615AssertType(local, "(union) => union"); 616AssertType(y, "union"); 617 618AssertType(x, "union"); 619 return x; 620 } 621 switch (typeof x) { 622AssertType(typeof x, "union"); 623AssertType(x, "union"); 624 625 case 'string': 626AssertType('string', "string"); 627 628 case 'number': 629AssertType('number', "string"); 630 631 default: 632AssertType(local(x), "union"); 633AssertType(local, "(union) => union"); 634AssertType(x, "union"); 635return local(x) 636 637 case 'string': 638AssertType('string', "string"); 639AssertType(assertNever(x), "never"); 640AssertType(assertNever, "(never) => never"); 641AssertType(x, "never"); 642return assertNever(x); 643 644 case 'number': 645AssertType('number', "string"); 646AssertType(assertNever(x), "never"); 647AssertType(assertNever, "(never) => never"); 648AssertType(x, "never"); 649return assertNever(x); 650 } 651} 652 653function fallThroughTest(x: string | number | boolean | object) { 654 switch (typeof x) { 655AssertType(typeof x, "union"); 656AssertType(x, "union"); 657 658 case 'number': 659AssertType('number', "string"); 660 661 assertNumber(x) 662AssertType(assertNumber(x), "number"); 663AssertType(assertNumber, "(number) => number"); 664AssertType(x, "number"); 665 666 case 'string': 667AssertType('string', "string"); 668 669 assertStringOrNumber(x) 670AssertType(assertStringOrNumber(x), "union"); 671AssertType(assertStringOrNumber, "(union) => union"); 672AssertType(x, "union"); 673 674 break; 675 default: 676 assertObject(x); 677AssertType(assertObject(x), "object"); 678AssertType(assertObject, "(object) => object"); 679AssertType(x, "object"); 680 681 case 'number': 682AssertType('number', "string"); 683 684 case 'boolean': 685AssertType('boolean', "string"); 686 687 assertBooleanOrObject(x); 688AssertType(assertBooleanOrObject(x), "union"); 689AssertType(assertBooleanOrObject, "(union) => union"); 690AssertType(x, "union"); 691 692 break; 693 } 694} 695 696function unknownNarrowing(x: unknown) { 697 switch (typeof x) { 698AssertType(typeof x, "union"); 699AssertType(x, "unknown"); 700 701 case 'number': assertNumber(x); 702AssertType('number', "string"); 703AssertType(assertNumber(x), "number"); 704AssertType(assertNumber, "(number) => number"); 705AssertType(x, "number"); 706return; 707 708 case 'boolean': assertBoolean(x); 709AssertType('boolean', "string"); 710AssertType(assertBoolean(x), "boolean"); 711AssertType(assertBoolean, "(boolean) => boolean"); 712AssertType(x, "boolean"); 713return; 714 715 case 'function': assertFunction(x); 716AssertType('function', "string"); 717AssertType(assertFunction(x), "Function"); 718AssertType(assertFunction, "(Function) => Function"); 719AssertType(x, "Function"); 720return; 721 722 case 'symbol': assertSymbol(x); 723AssertType('symbol', "string"); 724AssertType(assertSymbol(x), "symbol"); 725AssertType(assertSymbol, "(symbol) => symbol"); 726AssertType(x, "symbol"); 727return; 728 729 case 'object': assertObjectOrNull(x); 730AssertType('object', "string"); 731AssertType(assertObjectOrNull(x), "union"); 732AssertType(assertObjectOrNull, "(union) => union"); 733AssertType(x, "union"); 734return; 735 736 case 'string': assertString(x); 737AssertType('string', "string"); 738AssertType(assertString(x), "string"); 739AssertType(assertString, "(string) => string"); 740AssertType(x, "string"); 741return; 742 743 case 'undefined': assertUndefined(x); 744AssertType('undefined', "string"); 745AssertType(assertUndefined(x), "undefined"); 746AssertType(assertUndefined, "(undefined) => undefined"); 747AssertType(x, "undefined"); 748return; 749 } 750} 751 752function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) { 753 function assertKeyofS(k1: keyof S) { 754AssertType(assertKeyofS, "(keyof S) => void"); 755 756AssertType(k1, "keyof S"); 757} 758 759 switch (typeof k) { 760AssertType(typeof k, "union"); 761AssertType(k, "keyof S"); 762 763 case 'number': assertNumber(k); assertKeyofS(k); 764AssertType('number', "string"); 765AssertType(assertNumber(k), "number"); 766AssertType(assertNumber, "(number) => number"); 767AssertType(k, "number"); 768AssertType(assertKeyofS(k), "void"); 769AssertType(assertKeyofS, "(keyof S) => void"); 770AssertType(k, "keyof S & number"); 771return; 772 773 case 'symbol': assertSymbol(k); assertKeyofS(k); 774AssertType('symbol', "string"); 775AssertType(assertSymbol(k), "symbol"); 776AssertType(assertSymbol, "(symbol) => symbol"); 777AssertType(k, "symbol"); 778AssertType(assertKeyofS(k), "void"); 779AssertType(assertKeyofS, "(keyof S) => void"); 780AssertType(k, "keyof S & symbol"); 781return; 782 783 case 'string': assertString(k); assertKeyofS(k); 784AssertType('string', "string"); 785AssertType(assertString(k), "string"); 786AssertType(assertString, "(string) => string"); 787AssertType(k, "string"); 788AssertType(assertKeyofS(k), "void"); 789AssertType(assertKeyofS, "(keyof S) => void"); 790AssertType(k, "keyof S & string"); 791return; 792 } 793} 794 795function narrowingNarrows(x: {} | undefined) { 796 switch (typeof x) { 797AssertType(typeof x, "union"); 798AssertType(x, "union"); 799 800 case 'number': assertNumber(x); 801AssertType('number', "string"); 802AssertType(assertNumber(x), "number"); 803AssertType(assertNumber, "(number) => number"); 804AssertType(x, "number"); 805return; 806 807 case 'boolean': assertBoolean(x); 808AssertType('boolean', "string"); 809AssertType(assertBoolean(x), "boolean"); 810AssertType(assertBoolean, "(boolean) => boolean"); 811AssertType(x, "boolean"); 812return; 813 814 case 'function': assertFunction(x); 815AssertType('function', "string"); 816AssertType(assertFunction(x), "Function"); 817AssertType(assertFunction, "(Function) => Function"); 818AssertType(x, "Function"); 819return; 820 821 case 'symbol': assertSymbol(x); 822AssertType('symbol', "string"); 823AssertType(assertSymbol(x), "symbol"); 824AssertType(assertSymbol, "(symbol) => symbol"); 825AssertType(x, "symbol"); 826return; 827 828 case 'object': const _: {} = x; 829AssertType('object', "string"); 830AssertType(_, "{}"); 831AssertType(x, "object"); 832return; 833 834 case 'string': assertString(x); 835AssertType('string', "string"); 836AssertType(assertString(x), "string"); 837AssertType(assertString, "(string) => string"); 838AssertType(x, "string"); 839return; 840 841 case 'undefined': assertUndefined(x); 842AssertType('undefined', "string"); 843AssertType(assertUndefined(x), "undefined"); 844AssertType(assertUndefined, "(undefined) => undefined"); 845AssertType(x, "undefined"); 846return; 847 848 case 'number': assertNever(x); 849AssertType('number', "string"); 850AssertType(assertNever(x), "never"); 851AssertType(assertNever, "(never) => never"); 852AssertType(x, "never"); 853return; 854 855 default: const _y: {} = x; 856AssertType(_y, "{}"); 857AssertType(x, "{}"); 858return; 859 } 860} 861 862function narrowingNarrows2(x: true | 3 | 'hello' | undefined) { 863 switch (typeof x) { 864AssertType(typeof x, "union"); 865AssertType(x, "union"); 866 867 case 'number': assertNumber(x); 868AssertType('number', "string"); 869AssertType(assertNumber(x), "number"); 870AssertType(assertNumber, "(number) => number"); 871AssertType(x, "int"); 872return; 873 874 case 'boolean': assertBoolean(x); 875AssertType('boolean', "string"); 876AssertType(assertBoolean(x), "boolean"); 877AssertType(assertBoolean, "(boolean) => boolean"); 878AssertType(x, "boolean"); 879return; 880 881 case 'function': assertNever(x); 882AssertType('function', "string"); 883AssertType(assertNever(x), "never"); 884AssertType(assertNever, "(never) => never"); 885AssertType(x, "never"); 886return; 887 888 case 'symbol': assertNever(x); 889AssertType('symbol', "string"); 890AssertType(assertNever(x), "never"); 891AssertType(assertNever, "(never) => never"); 892AssertType(x, "never"); 893return; 894 895 case 'object': const _: {} = assertNever(x); 896AssertType('object', "string"); 897AssertType(_, "{}"); 898AssertType(assertNever(x), "never"); 899AssertType(assertNever, "(never) => never"); 900AssertType(x, "never"); 901return; 902 903 case 'string': assertString(x); 904AssertType('string', "string"); 905AssertType(assertString(x), "string"); 906AssertType(assertString, "(string) => string"); 907AssertType(x, "string"); 908return; 909 910 case 'undefined': assertUndefined(x); 911AssertType('undefined', "string"); 912AssertType(assertUndefined(x), "undefined"); 913AssertType(assertUndefined, "(undefined) => undefined"); 914AssertType(x, "undefined"); 915return; 916 917 case 'number': assertNever(x); 918AssertType('number', "string"); 919AssertType(assertNever(x), "never"); 920AssertType(assertNever, "(never) => never"); 921AssertType(x, "never"); 922return; 923 924 default: const _y: {} = assertNever(x); 925AssertType(_y, "{}"); 926AssertType(assertNever(x), "never"); 927AssertType(assertNever, "(never) => never"); 928AssertType(x, "never"); 929return; 930 } 931} 932 933/* Template literals */ 934 935function testUnionWithTempalte(x: Basic) { 936 switch (typeof x) { 937AssertType(typeof x, "union"); 938AssertType(x, "Basic"); 939 940 case `number`: assertNumber(x); 941AssertType(`number`, "string"); 942AssertType(assertNumber(x), "number"); 943AssertType(assertNumber, "(number) => number"); 944AssertType(x, "number"); 945return; 946 947 case `boolean`: assertBoolean(x); 948AssertType(`boolean`, "string"); 949AssertType(assertBoolean(x), "boolean"); 950AssertType(assertBoolean, "(boolean) => boolean"); 951AssertType(x, "boolean"); 952return; 953 954 case `function`: assertFunction(x); 955AssertType(`function`, "string"); 956AssertType(assertFunction(x), "Function"); 957AssertType(assertFunction, "(Function) => Function"); 958AssertType(x, "Function"); 959return; 960 961 case `symbol`: assertSymbol(x); 962AssertType(`symbol`, "string"); 963AssertType(assertSymbol(x), "symbol"); 964AssertType(assertSymbol, "(symbol) => symbol"); 965AssertType(x, "symbol"); 966return; 967 968 case `object`: assertObject(x); 969AssertType(`object`, "string"); 970AssertType(assertObject(x), "object"); 971AssertType(assertObject, "(object) => object"); 972AssertType(x, "object"); 973return; 974 975 case `string`: assertString(x); 976AssertType(`string`, "string"); 977AssertType(assertString(x), "string"); 978AssertType(assertString, "(string) => string"); 979AssertType(x, "string"); 980return; 981 982 case `undefined`: assertUndefined(x); 983AssertType(`undefined`, "string"); 984AssertType(assertUndefined(x), "undefined"); 985AssertType(assertUndefined, "(undefined) => undefined"); 986AssertType(x, "undefined"); 987return; 988 } 989 assertNever(x); 990AssertType(assertNever(x), "never"); 991AssertType(assertNever, "(never) => never"); 992AssertType(x, "never"); 993} 994 995function fallThroughTestWithTempalte(x: string | number | boolean | object) { 996 switch (typeof x) { 997AssertType(typeof x, "union"); 998AssertType(x, "union"); 999 1000 case `number`: 1001AssertType(`number`, "string"); 1002 1003 assertNumber(x) 1004AssertType(assertNumber(x), "number"); 1005AssertType(assertNumber, "(number) => number"); 1006AssertType(x, "number"); 1007 1008 case `string`: 1009AssertType(`string`, "string"); 1010 1011 assertStringOrNumber(x) 1012AssertType(assertStringOrNumber(x), "union"); 1013AssertType(assertStringOrNumber, "(union) => union"); 1014AssertType(x, "union"); 1015 1016 break; 1017 default: 1018 assertObject(x); 1019AssertType(assertObject(x), "object"); 1020AssertType(assertObject, "(object) => object"); 1021AssertType(x, "object"); 1022 1023 case `number`: 1024AssertType(`number`, "string"); 1025 1026 case `boolean`: 1027AssertType(`boolean`, "string"); 1028 1029 assertBooleanOrObject(x); 1030AssertType(assertBooleanOrObject(x), "union"); 1031AssertType(assertBooleanOrObject, "(union) => union"); 1032AssertType(x, "union"); 1033 1034 break; 1035 } 1036} 1037 1038function keyofNarrowingWithTemplate<S extends { [K in keyof S]: string }>(k: keyof S) { 1039 function assertKeyofS(k1: keyof S) { 1040AssertType(assertKeyofS, "(keyof S) => void"); 1041 1042AssertType(k1, "keyof S"); 1043} 1044 1045 switch (typeof k) { 1046AssertType(typeof k, "union"); 1047AssertType(k, "keyof S"); 1048 1049 case `number`: assertNumber(k); assertKeyofS(k); 1050AssertType(`number`, "string"); 1051AssertType(assertNumber(k), "number"); 1052AssertType(assertNumber, "(number) => number"); 1053AssertType(k, "number"); 1054AssertType(assertKeyofS(k), "void"); 1055AssertType(assertKeyofS, "(keyof S) => void"); 1056AssertType(k, "keyof S & number"); 1057return; 1058 1059 case `symbol`: assertSymbol(k); assertKeyofS(k); 1060AssertType(`symbol`, "string"); 1061AssertType(assertSymbol(k), "symbol"); 1062AssertType(assertSymbol, "(symbol) => symbol"); 1063AssertType(k, "symbol"); 1064AssertType(assertKeyofS(k), "void"); 1065AssertType(assertKeyofS, "(keyof S) => void"); 1066AssertType(k, "keyof S & symbol"); 1067return; 1068 1069 case `string`: assertString(k); assertKeyofS(k); 1070AssertType(`string`, "string"); 1071AssertType(assertString(k), "string"); 1072AssertType(assertString, "(string) => string"); 1073AssertType(k, "string"); 1074AssertType(assertKeyofS(k), "void"); 1075AssertType(assertKeyofS, "(keyof S) => void"); 1076AssertType(k, "keyof S & string"); 1077return; 1078 } 1079} 1080 1081/* Both string literals and template literals */ 1082 1083function multipleGenericFuseWithBoth<X extends L | number, Y extends R | number>(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { 1084 switch (typeof xy) { 1085AssertType(typeof xy, "union"); 1086AssertType(xy, "union"); 1087 1088 case `function`: 1089AssertType(`function`, "string"); 1090AssertType([xy, 1], "[X & Function, 1]"); 1091AssertType(xy, "X & Function"); 1092AssertType(1, "int"); 1093return [xy, 1]; 1094 1095 case 'object': 1096AssertType('object', "string"); 1097AssertType([xy, 'two'], "[Y & object, string]"); 1098AssertType(xy, "Y & object"); 1099AssertType('two', "string"); 1100return [xy, 'two']; 1101 1102 case `number`: 1103AssertType(`number`, "string"); 1104AssertType([xy], "[union]"); 1105AssertType(xy, "union"); 1106return [xy] 1107 } 1108} 1109 1110 1111