1.. Copyright (c) 2021-2024 Huawei Device Co., Ltd. 2 Licensed under the Apache License, Version 2.0 (the "License"); 3 you may not use this file except in compliance with the License. 4 You may obtain a copy of the License at 5 http://www.apache.org/licenses/LICENSE-2.0 6 Unless required by applicable law or agreed to in writing, software 7 distributed under the License is distributed on an "AS IS" BASIS, 8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 See the License for the specific language governing permissions and 10 limitations under the License. 11 12Recipes 13======= 14 15.. _R001: 16 17|CB_R| #1: Objects with property names that are not identifiers are not supported 18--------------------------------------------------------------------------------- 19 20|CB_RULE| 21~~~~~~~~~ 22 23|LANG| does not support Objects with name properties that are numbers or 24strings. Use classes to access data by property names. Use arrays to access data 25by numeric indices. 26 27|CB_BAD| 28~~~~~~~~ 29 30.. code-block:: typescript 31 32 var x = {"name": 1, 2: 3} 33 34 console.log(x["name"]) 35 console.log(x[2]) 36 37|CB_OK| 38~~~~~~~ 39 40.. code-block:: typescript 41 42 class X { 43 public name: number 44 } 45 let x = {name: 1} 46 console.log(x.name) 47 48 let y = [1, 2, 3] 49 console.log(y[2]) 50 51 // If you still need a container to store keys of different types, 52 // use Map<Object, some_type>: 53 let z = new Map<Object, number>() 54 z.set("name", 1) 55 z.set(2, 2) 56 console.log(z.get("name")) 57 console.log(z.get(2)) 58 59|CB_SEE| 60~~~~~~~~ 61 62* :ref:`R002` 63* :ref:`R052` 64* :ref:`R059` 65* :ref:`R060` 66* :ref:`R066` 67* :ref:`R105` 68* :ref:`R109` 69 70.. _R002: 71 72|CB_R| #2: ``Symbol()`` API is not supported 73-------------------------------------------- 74 75|CB_RULE| 76~~~~~~~~~ 77 78|LANG| does not support ``Symbol()`` API. 79 80|CB_BAD| 81~~~~~~~~ 82 83|TS| has ``Symbol()`` API, which can be used among other things to generate 84unique property names at runtime: 85 86.. code-block:: typescript 87 88 const sym = Symbol() 89 let o = { 90 [sym]: "value" 91 } 92 93|CB_OK| 94~~~~~~~ 95 96|LANG| does not support ``Symbol()`` API because its most popular use cases 97make no sense in the statically typed environment. In particular, the object 98layout is defined at compile time and cannot be changed at runtime. 99 100|CB_SEE| 101~~~~~~~~ 102 103* :ref:`R001` 104* :ref:`R052` 105* :ref:`R059` 106* :ref:`R060` 107* :ref:`R066` 108* :ref:`R105` 109* :ref:`R109` 110 111.. _R003: 112 113|CB_R| #3: Private '#' identifiers are not supported 114---------------------------------------------------- 115 116|CB_RULE| 117~~~~~~~~~ 118 119|LANG| does not private identifiers started with ``#`` symbol, use ``private`` keyword instead. 120 121|CB_BAD| 122~~~~~~~~ 123 124.. code-block:: typescript 125 126 class C { 127 foo = 1 128 } 129 130|CB_OK| 131~~~~~~~ 132 133.. code-block:: typescript 134 135 class C { 136 private foo = 1 137 } 138 139 140.. _R004: 141 142|CB_R| #4: Use unique names for types, namespaces, etc. 143------------------------------------------------------- 144 145|CB_RULE| 146~~~~~~~~~ 147 148Names for types, namespaces and so on must be unique and distinct from other 149names, e.g., variable names. 150 151|CB_BAD| 152~~~~~~~~ 153 154.. code-block:: typescript 155 156 let X: string 157 type X = number[] // Type alias with the same name as the variable 158 159|CB_OK| 160~~~~~~~ 161 162.. code-block:: typescript 163 164 let X: string 165 type T = number[] // X is not allowed here to avoid name collisions 166 167.. _R005: 168 169|CB_R| #5: Use ``let`` instead of ``var`` 170----------------------------------------- 171 172|CB_RULE| 173~~~~~~~~~ 174 175|LANG| does not support ``var``, always use ``let`` instead. 176 177|CB_BAD| 178~~~~~~~~ 179 180.. code-block:: typescript 181 182 function f(shouldInitialize: boolean) { 183 if (shouldInitialize) { 184 var x = 10 185 } 186 return x 187 } 188 189 console.log(f(true)) // 10 190 console.log(f(false)) // undefined 191 192 let upper_let = 0 193 { 194 var scoped_var = 0 195 let scoped_let = 0 196 upper_let = 5 197 } 198 scoped_var = 5 // Visible 199 scoped_let = 5 // Compile-time error 200 201|CB_OK| 202~~~~~~~ 203 204.. code-block:: typescript 205 206 function f(shouldInitialize: boolean): Object { 207 let x: Object = new Object(); 208 if (shouldInitialize) { 209 x = 10 210 } 211 return x 212 } 213 214 console.log(f(true)); // 10 215 console.log(f(false)); // {} 216 217 let upper_let = 0 218 let scoped_var = 0 219 { 220 let scoped_let = 0 221 upper_let = 5 222 } 223 scoped_var = 5 224 scoped_let = 5 // Compile-time error 225 226.. _R008: 227 228|CB_R| #8: Use explicit types instead of ``any``, ``undefined``, ``unknown`` 229---------------------------------------------------------------------------- 230 231|CB_RULE| 232~~~~~~~~~ 233 234|LANG| does not support ``any``, ``undefined``, and ``unknown`` types. 235Specify types explicitly. 236 237|CB_BAD| 238~~~~~~~~ 239 240.. code-block:: typescript 241 242 var x 243 console.log(x) // undefined 244 245 var y: any 246 console.log(y) // undefined 247 248|CB_OK| 249~~~~~~~ 250 251.. code-block:: typescript 252 253 // All variables should have their types specified explicitly: 254 let x: Object = {} 255 console.log(x) // {} 256 257|CB_SEE| 258~~~~~~~~ 259 260.. _R009: 261 262|CB_R| #9: You can extend your |TS| code with more numeric types 263---------------------------------------------------------------- 264 265|CB_RULE| 266~~~~~~~~~ 267 268|LANG| supports different numeric types on top of just ``number``. 269 270|CB_BAD| 271~~~~~~~~ 272 273|TS| supports ``number`` as the only numeric type: 274 275.. code-block:: typescript 276 277 let x: number = 1 278 279|CB_OK| 280~~~~~~~ 281 282|LANG| supports several numeric types: 283 284+-----------+----------+-------------------------------------------------------------+ 285| Type | Size | Range | 286+===========+==========+=============================================================+ 287|``byte`` | 8 bits |``[-128 .. 127]`` | 288+-----------+----------+-------------------------------------------------------------+ 289|``short`` | 16 bits |``[-32,768 .. 32,767]`` | 290+-----------+----------+-------------------------------------------------------------+ 291|``int`` | 32 bits |``[-2,147,483,648 .. 2,147,483,647]`` | 292+-----------+----------+-------------------------------------------------------------+ 293|``long`` | 64 bits |``[-9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807]``| 294+-----------+----------+-------------------------------------------------------------+ 295|``ubyte`` | 8 bits |``[0 .. 255]`` | 296+-----------+----------+-------------------------------------------------------------+ 297|``ushort`` | 16 bits |``[0 .. 65,535]`` | 298+-----------+----------+-------------------------------------------------------------+ 299|``uint`` | 32 bits |``[0 .. 4,294,967,295]`` | 300+-----------+----------+-------------------------------------------------------------+ 301|``ulong`` | 64 bits |``[0 .. 18,446,744,073,709,551,615]`` | 302+-----------+----------+-------------------------------------------------------------+ 303|``float`` | 32 bits |``3.4E +/- 38 (7 digits)`` | 304+-----------+----------+-------------------------------------------------------------+ 305|``double`` | 64 bits |``1.7E +/- 308 (15 digits)`` | 306+-----------+----------+-------------------------------------------------------------+ 307 308Additionally, |LANG| supports the following types: 309 310* Character type ``char`` (the range of values is the same as ``ushort``) 311* Boolean type ``boolean`` (values: ``true``, ``false``) 312 313.. code-block:: typescript 314 315 let x: int = 1 316 let y: boolean = true 317 let z: char = 'a' 318 319.. _R010: 320 321|CB_R| #10: Use ``long`` instead of ``bigint`` 322---------------------------------------------- 323 324|CB_RULE| 325~~~~~~~~~ 326 327Use ``long`` to work with 64-bit integers. 328 329|CB_BAD| 330~~~~~~~~ 331 332|TS| supports ``bigint`` data type, but this feature is available only since 333ES2020 and requires ``n`` suffix for numeric literals: 334 335.. code-block:: typescript 336 337 let a: bigint = 1n 338 339|CB_OK| 340~~~~~~~ 341 342|LANG| provides ``long`` data type to work with 64-bit 343integers, ``n`` suffix is not supported: 344 345.. code-block:: typescript 346 347 let x: long = 1 348 349.. _R012: 350 351|CB_R| #12: Use ``T[]`` instead of ``Array<T>`` to declare arrays 352----------------------------------------------------------------- 353 354|CB_RULE| 355~~~~~~~~~ 356 357In |TS|, arrays can be declared as either ``Array<T>`` or ``T[]``. Currently, 358|LANG| supports only the second syntax for array declaration. 359 360|CB_BAD| 361~~~~~~~~ 362 363.. code-block:: typescript 364 365 // These are equivalent in TypeScript: 366 let y: Array<string> = ["1", "2", "3"] 367 368|CB_OK| 369~~~~~~~ 370 371.. code-block:: typescript 372 373 let x: string[] = ["1", "2", "3"]; 374 let y: string[] = ["1", "2", "3"]; // Array<string> is not supported currently 375 376.. _R014: 377 378|CB_R| #14: Use ``class`` instead of a type with call signature 379--------------------------------------------------------------- 380 381|CB_RULE| 382~~~~~~~~~ 383 384|LANG| does not support call signatures in object types. Use classes instead. 385 386|CB_BAD| 387~~~~~~~~ 388 389.. code-block:: typescript 390 391 type DescribableFunction = { 392 description: string 393 (someArg: number): string // call signature 394 } 395 396 function doSomething(fn: DescribableFunction): void { 397 console.log(fn.description + " returned " + fn(6)) 398 } 399 400|CB_OK| 401~~~~~~~ 402 403.. code-block:: typescript 404 405 class DescribableFunction { 406 description: string; 407 public invoke(someArg: number): string { 408 return someArg.toString() 409 } 410 constructor() { 411 this.description = "desc" 412 } 413 } 414 415 function doSomething(fn: DescribableFunction): void { 416 console.log(fn.description + " returned " + fn.invoke(6)) 417 } 418 419 doSomething(new DescribableFunction()); 420 421|CB_SEE| 422~~~~~~~~ 423 424* :ref:`R015` 425 426.. _R015: 427 428|CB_R| #15: Use ``class`` instead of a type with constructor signature 429---------------------------------------------------------------------- 430 431|CB_RULE| 432~~~~~~~~~ 433 434|LANG| does not support constructor signatures in object types. Use classes 435instead. 436 437|CB_BAD| 438~~~~~~~~ 439 440.. code-block:: typescript 441 442 class SomeObject {} 443 444 type SomeConstructor = { 445 new (s: string): SomeObject 446 } 447 448 function fn(ctor: SomeConstructor) { 449 return new ctor("hello"); 450 } 451 452|CB_OK| 453~~~~~~~ 454 455.. code-block:: typescript 456 457 class SomeObject { 458 public f: string 459 constructor (s: string) { 460 this.f = s 461 } 462 } 463 464 function fn(s: string): SomeObject { 465 return new SomeObject(s) 466 } 467 468|CB_SEE| 469~~~~~~~~ 470 471* :ref:`R014` 472 473.. _R016: 474 475|CB_R| #16: Only one static block is supported 476---------------------------------------------- 477 478|CB_RULE| 479~~~~~~~~~ 480 481|LANG| does not allow to have sevaral static block for class initialization, combine static blocks statements to the one static block. 482 483|CB_BAD| 484~~~~~~~~ 485 486.. code-block:: typescript 487 488 class C { 489 static s: string 490 491 static { 492 C.s = "aa" 493 } 494 static { 495 C.s = C.s + "bb" 496 } 497 } 498 499|CB_OK| 500~~~~~~~ 501 502.. code-block:: typescript 503 504 505 class C { 506 static s: string 507 508 static { 509 C.s = "aa" 510 C.s = C.s + "bb" 511 } 512 } 513 514 515.. _R017: 516 517|CB_R| #17: Indexed signatures are not supported 518------------------------------------------------ 519 520|CB_RULE| 521~~~~~~~~~ 522 523|LANG| does not allow indexed signatures, use arrays instead. 524 525|CB_BAD| 526~~~~~~~~ 527 528.. code-block:: typescript 529 530 // Interface with an indexed signature: 531 interface StringArray { 532 [index: number]: string 533 } 534 535 const myArray: StringArray = getStringArray() 536 const secondItem = myArray[1] 537 538|CB_OK| 539~~~~~~~ 540 541.. code-block:: typescript 542 543 class X { 544 public f: string[] 545 } 546 547 let myArray: X = new X() 548 const secondItem = myArray.f[1] 549 550.. _R019: 551 552|CB_R| #19: Use inheritance instead of intersection types 553--------------------------------------------------------- 554 555|CB_RULE| 556~~~~~~~~~ 557 558Currently, |LANG| does not support intersection types. You can use inheritance 559as a work-around. 560 561|CB_BAD| 562~~~~~~~~ 563 564.. code-block:: typescript 565 566 interface Identity { 567 id: number 568 name: string 569 } 570 571 interface Contact { 572 email: string 573 phone: string 574 } 575 576 type Employee = Identity & Contact 577 578|CB_OK| 579~~~~~~~ 580 581.. code-block:: typescript 582 583 interface Identity { 584 id: number 585 name: string 586 } 587 588 interface Contact { 589 email: string 590 phone: string 591 } 592 593 interface Employee extends Identity, Contact {} 594 595.. _R021: 596 597|CB_R| #21: Returning ``this`` type is not supported 598---------------------------------------------------- 599 600|CB_RULE| 601~~~~~~~~~ 602 603|LANG| does not support the returning ``this`` type. Use explicit type instead. 604 605|CB_BAD| 606~~~~~~~~ 607 608.. code-block:: typescript 609 610 interface ListItem { 611 getHead(): this 612 } 613 614|CB_OK| 615~~~~~~~ 616 617.. code-block:: typescript 618 619 interface ListItem { 620 getHead(): ListItem 621 } 622 623.. _R023: 624 625|CB_R| #22: Conditional types are not supported 626---------------------------------------------------- 627 628|CB_RULE| 629~~~~~~~~~ 630 631|LANG| does not support conditional type aliases. Introduce a new type with constraints explicitly or rewrite logic with use of ``Object``. 632``infer`` keyword is not supported. 633 634|CB_BAD| 635~~~~~~~~ 636 637.. code-block:: typescript 638 639 type X<T> = T extends number ? T : never 640 641 type Y<T> = T extends Array<infer Item> ? Item : never 642 643|CB_OK| 644~~~~~~~ 645 646.. code-block:: typescript 647 648 // Provide explicit contraints within type alias 649 type X1<T extends number> = T 650 651 // Rewrite with Object. Less type control, need more type checks for safety 652 type X2<T> = Object 653 654 // Item has to be used as a generic parameter and need to be properly instantiated 655 type YI<Item, T extends Array<Item>> = Item 656 657 658|CB_R| #23: Type queries are not supported 659------------------------------------------ 660 661|CB_RULE| 662~~~~~~~~~ 663 664Currently, |LANG| does not support specifying types via ``typeof``. 665All types must be specified explicitly. 666 667|CB_BAD| 668~~~~~~~~ 669 670.. code-block:: typescript 671 672 var a = {x: 10, y: 20} 673 var b: typeof a 674 675|CB_OK| 676~~~~~~~ 677 678.. code-block:: typescript 679 680 class A { 681 public x: number = 10 682 public y: number = 20 683 } 684 685 let a: A 686 let b: A 687 688.. _R025: 689 690|CB_R| #25: Declaring fields in ``constructor`` is not supported 691---------------------------------------------------------------- 692 693|CB_RULE| 694~~~~~~~~~ 695 696|LANG| does not support declaring class fields in the ``constructor``. 697You must declare them inside the ``class`` declaration instead. 698 699|CB_BAD| 700~~~~~~~~ 701 702.. code-block:: typescript 703 704 class Person { 705 constructor( 706 protected ssn: string, 707 private firstName: string, 708 private lastName: string 709 ) { 710 this.ssn = ssn 711 this.firstName = firstName 712 this.lastName = lastName 713 } 714 715 getFullName(): string { 716 return this.firstName + " " + this.lastName 717 } 718 } 719 720|CB_OK| 721~~~~~~~ 722 723.. code-block:: typescript 724 725 class Person { 726 protected ssn: string 727 private firstName: string 728 private lastName: string 729 730 constructor(ssn: string, firstName: string, lastName: string) { 731 this.ssn = ssn 732 this.firstName = firstName 733 this.lastName = lastName 734 } 735 736 getFullName(): string { 737 return this.firstName + " " + this.lastName 738 } 739 } 740 741.. _R027: 742 743|CB_R| #27: Construct signatures not supported in interfaces 744------------------------------------------------------------ 745 746|CB_RULE| 747~~~~~~~~~ 748 749|LANG| does not support construct signatures. Use methods instead. 750 751|CB_BAD| 752~~~~~~~~ 753 754.. code-block:: typescript 755 756 interface I { 757 new (s: string): I 758 } 759 760 function fn(i: I) { 761 return new i("hello"); 762 } 763 764|CB_OK| 765~~~~~~~ 766 767.. code-block:: typescript 768 769 interface I { 770 create(s: string): I 771 } 772 773 function fn(i: I) { 774 return i.create("hello") 775 } 776 777|CB_SEE| 778~~~~~~~~ 779 780* :ref:`R015` 781 782.. _R028: 783 784|CB_R| #28: Indexed access types are not supported 785-------------------------------------------------- 786 787|CB_RULE| 788~~~~~~~~~ 789 790|LANG| does not support indexed access types. Use the type name instead. 791 792|CB_BAD| 793~~~~~~~~ 794 795.. code-block:: typescript 796 797 type Point = {x: number, y: number} 798 type N = Point["x"] // is equal to number 799 800|CB_OK| 801~~~~~~~ 802 803.. code-block:: typescript 804 805 class Point {x: number = 0; y: number = 0} 806 type N = number 807 808.. _R029: 809 810|CB_R| #29: Indexed access is not supported for fields 811------------------------------------------------------ 812 813|CB_RULE| 814~~~~~~~~~ 815 816|LANG| does not support indexed access for class fields. Use dot notation instead. 817 818|CB_BAD| 819~~~~~~~~ 820 821.. code-block:: typescript 822 823 class Point {x: number = 0; y: number = 0} 824 let p: Point = {x: 1, y: 2} 825 let x = p["x"] 826 827|CB_OK| 828~~~~~~~ 829 830.. code-block:: typescript 831 832 class Point {x: number = 0; y: number = 0} 833 let p: Point = {x: 1, y: 2} 834 let x = p.x 835 836.. _R030: 837 838|CB_R| #30: Structural identity is not supported 839------------------------------------------------ 840 841|CB_RULE| 842~~~~~~~~~ 843 844Currently, |LANG| does not support structural identity, i.e., the compiler 845cannot compare two types' public APIs and decide whether such types are 846identical. Use other mechanisms (inheritance, interfaces or type aliases) 847instead. 848 849In |TS|, types ``X`` and ``Y`` are equal (interchangeble), while in |LANG| 850they are not. 851 852|CB_BAD| 853~~~~~~~~ 854 855.. code-block:: typescript 856 857 interface X { 858 f(): string 859 } 860 861 interface Y { // Y is equal to X 862 f(): string 863 } 864 865|CB_OK| 866~~~~~~~ 867 868|LANG| does not support structural identity. In the static environment the 869compiler checks if two classes or interfaces are equal, but there is no way 870to compare unrelated (by inheritance or interface) classes that are 871structurally equivalent. 872 873.. code-block:: typescript 874 875 interface X { 876 f(): string 877 } 878 879 type Y = X // Y is equal to X 880 881|CB_SEE| 882~~~~~~~~ 883 884* :ref:`R031` 885* :ref:`R032` 886* :ref:`R035` 887 888 889.. _R031: 890 891|CB_R| #31: Structural typing is not supported for subtyping / supertyping 892-------------------------------------------------------------------------- 893 894|CB_RULE| 895~~~~~~~~~ 896 897Currently, |LANG| does not check structural equivalence for type inference, i.e., 898the compiler cannot compare two types' public APIs and decide whether such types 899are identical. 900Use other mechanisms (inheritance or interfaces) instead. 901 902|CB_BAD| 903~~~~~~~~ 904 905.. code-block:: typescript 906 907 class X { 908 public foo: number 909 910 constructor() { 911 this.foo = 0 912 } 913 } 914 915 class Y { 916 public foo: number 917 918 constructor() { 919 this.foo = 0 920 } 921 } 922 923 let x = new X() 924 let y = new Y() 925 926 console.log("Assign X to Y") 927 y = x 928 929 console.log("Assign Y to X") 930 x = y 931 932 933|CB_OK| 934~~~~~~~ 935 936.. code-block:: typescript 937 938 class X { 939 public foo: number 940 941 constructor() { 942 this.foo = 0 943 } 944 } 945 946 // Y is derived from X, which explicitly set subtype / supertype relations: 947 class Y extends X { 948 constructor() { 949 super() 950 } 951 } 952 953 let x = new X() 954 let y = new Y() 955 956 console.log("Assign X to Y") 957 y = x // ok, X is the super class of X 958 959 // Cannot assign Y to X 960 //x = y - compile-time error 961 962 963|CB_SEE| 964~~~~~~~~ 965 966* :ref:`R030` 967* :ref:`R032` 968* :ref:`R035` 969 970.. _R032: 971 972|CB_R| #32: Structural typing is not supported for assignability checks 973----------------------------------------------------------------------- 974 975|CB_RULE| 976~~~~~~~~~ 977 978Currently, |LANG| does not check structural equivalence when checking if types 979are assignable to each other, i.e., the compiler cannot compare two types' 980public APIs and decide whether such types are identical. Use other mechanisms 981(inheritance or interfaces) instead. 982 983|CB_BAD| 984~~~~~~~~ 985 986.. code-block:: typescript 987 988 class X { 989 public foo: number 990 991 constructor() { 992 this.foo = 0 993 } 994 } 995 996 class Y { 997 public foo: number 998 constructor() { 999 this.foo = 0 1000 } 1001 } 1002 1003 let x = new X() 1004 let y = new Y() 1005 1006 console.log("Assign X to Y") 1007 y = x 1008 1009 console.log("Assign Y to X") 1010 x = y 1011 1012|CB_OK| 1013~~~~~~~ 1014 1015.. code-block:: typescript 1016 1017 interface Z { 1018 foo: number 1019 } 1020 1021 // X implements interface Z, which makes relation between X and Y explicit. 1022 class X implements Z { 1023 public foo: number 1024 1025 constructor() { 1026 this.foo = 0 1027 } 1028 } 1029 1030 // Y implements interface Z, which makes relation between X and Y explicit. 1031 class Y implements Z { 1032 public foo: number 1033 1034 constructor() { 1035 this.foo = 0 1036 } 1037 } 1038 1039 let x: Z = new X() 1040 let y: Z = new Y() 1041 1042 console.log("Assign X to Y") 1043 y = x // ok, both are of the same type 1044 1045 console.log("Assign Y to X") 1046 x = y // ok, both are of the same type 1047 1048|CB_SEE| 1049~~~~~~~~ 1050 1051* :ref:`R030` 1052* :ref:`R031` 1053* :ref:`R035` 1054 1055.. _R034: 1056 1057|CB_R| #34: Generic functions must be called with explicit type specialization 1058------------------------------------------------------------------------------ 1059 1060|CB_RULE| 1061~~~~~~~~~ 1062 1063Currently, |LANG| does not support inference of type parameters in case of calls 1064to generic functions. If a function is declared generic, all calls must specify 1065type parameters explicitly. 1066 1067|CB_BAD| 1068~~~~~~~~ 1069 1070.. code-block:: typescript 1071 1072 function choose<T>(x: T, y: T): T { 1073 return Math.random() < 0.5 ? x : y 1074 } 1075 1076 let x = choose(10, 20) // Ok 1077 let y = choose("10", 20) // Compile-time error 1078 1079|CB_OK| 1080~~~~~~~ 1081 1082.. code-block:: typescript 1083 1084 function choose<T>(x: T, y: T): T { 1085 return Math.random() < 0.5 ? x : y 1086 } 1087 1088 let x = choose<number>(10, 20) // Ok 1089 let y = choose<number>("10", 20) // Compile-time error 1090 1091.. _R035: 1092 1093|CB_R| #35: Structural typing is not supported for type inference 1094----------------------------------------------------------------- 1095 1096|CB_RULE| 1097~~~~~~~~~ 1098 1099Currently, |LANG| does not support structural typing, i.e., the compiler cannot 1100compare two types' public APIs and decide whether such types are identical. 1101Use inheritance and interfaces to specify the relation between the types 1102explicitly. 1103 1104|CB_BAD| 1105~~~~~~~~ 1106 1107.. code-block:: typescript 1108 1109 class X { 1110 public foo: number 1111 private s: string 1112 1113 constructor (f: number) { 1114 this.foo = f 1115 this.s = "" 1116 } 1117 1118 public say(): void { 1119 console.log("X = ", this.foo) 1120 } 1121 } 1122 1123 class Y { 1124 public foo: number 1125 1126 constructor (f: number) { 1127 this.foo = f 1128 } 1129 public say(): void { 1130 console.log("Y = ", this.foo) 1131 } 1132 } 1133 1134 function bar(z: X): void { 1135 z.say() 1136 } 1137 1138 // X and Y are equivalent because their public API is equivalent. 1139 // Thus the second call is allowed: 1140 bar(new X(1)); 1141 bar(new Y(2)); 1142 1143|CB_OK| 1144~~~~~~~ 1145 1146.. code-block:: typescript 1147 1148 interface Z { 1149 say(): void 1150 } 1151 1152 class X implements Z { 1153 public foo: number 1154 private s: string 1155 1156 constructor (f: number) { 1157 this.foo = f 1158 this.s = "" 1159 } 1160 public say(): void { 1161 console.log("X = ", this.foo) 1162 } 1163 } 1164 1165 class Y implements Z { 1166 public foo: number 1167 1168 constructor (f: number) { 1169 this.foo = f 1170 } 1171 public say(): void { 1172 console.log("Y = ", this.foo) 1173 } 1174 } 1175 1176 function bar(z: Z): void { 1177 z.say() 1178 } 1179 1180 // X and Y implement the same interface Z, thus both calls are allowed: 1181 bar(new X(1)) 1182 bar(new Y(2)) 1183 1184|CB_SEE| 1185~~~~~~~~ 1186 1187* :ref:`R030` 1188* :ref:`R031` 1189* :ref:`R032` 1190 1191.. _R037: 1192 1193|CB_R| #37: RegExp literals are not supported 1194--------------------------------------------- 1195 1196|CB_RULE| 1197~~~~~~~~~ 1198 1199Currently, |LANG| does not support RegExp literals. Use library call with string 1200literals instead. 1201 1202|CB_BAD| 1203~~~~~~~~ 1204 1205.. code-block:: typescript 1206 1207 let regex: RegExp = /bc*d/ 1208 1209|CB_OK| 1210~~~~~~~ 1211 1212.. code-block:: typescript 1213 1214 let regex: RegExp = new RegExp("/bc*d/") 1215 1216.. _R038: 1217 1218|CB_R| #38: Object literal must correspond to explicitly declared class or interface 1219------------------------------------------------------------------------------------ 1220 1221|CB_RULE| 1222~~~~~~~~~ 1223 1224|LANG| supports the usage of object literals if the compiler can infer 1225to what classes or interfaces such literals correspond to. 1226Otherwise, a compile-time error occurs. 1227 1228The class or interface can be specified as a type annotation for a variable. 1229 1230|CB_BAD| 1231~~~~~~~~ 1232 1233.. code-block:: typescript 1234 1235 let x = {f: 1} 1236 1237|CB_OK| 1238~~~~~~~ 1239 1240.. code-block:: typescript 1241 1242 class O { 1243 f: number 1244 } 1245 1246 let x: O = {f: 1} // OK 1247 let y = {f: 1} // Compile-time error, cannot infer object literal type 1248 let z: Object = {f: 2} // Compile-time error, class 'Object' does not have field 'f' 1249 1250|CB_SEE| 1251~~~~~~~~ 1252 1253* :ref:`R040` 1254* :ref:`R043` 1255 1256.. _R040: 1257 1258|CB_R| #40: Object literals cannot be used as type declarations 1259--------------------------------------------------------------- 1260 1261|CB_RULE| 1262~~~~~~~~~ 1263 1264|LANG| does not support the usage of object literals to declare 1265types in place. Declare classes and interfaces explicitly instead. 1266 1267|CB_BAD| 1268~~~~~~~~ 1269 1270.. code-block:: typescript 1271 1272 let o: {x: number, y: number} = { 1273 x: 2, 1274 y: 3 1275 } 1276 1277 type T = G<{x: number, y: number}> 1278 1279|CB_OK| 1280~~~~~~~ 1281 1282.. code-block:: typescript 1283 1284 class O { 1285 x: number 1286 y: number 1287 } 1288 1289 let o: O = {x: 2, y: 3} 1290 1291 type T = G<O> 1292 1293|CB_SEE| 1294~~~~~~~~ 1295 1296* :ref:`R038` 1297* :ref:`R043` 1298 1299.. _R043: 1300 1301|CB_R| #43: Untyped array literals are not supported 1302---------------------------------------------------- 1303 1304|CB_RULE| 1305~~~~~~~~~ 1306 1307|LANG| does not support the usage of untyped array literals. The type of an 1308array element must be inferred from the context. Use the type ``Object`` to 1309define mixed types array. 1310 1311|CB_BAD| 1312~~~~~~~~ 1313 1314.. code-block:: typescript 1315 1316 let x = [1, 2] 1317 let y = [1, "aa"] 1318 1319|CB_OK| 1320~~~~~~~ 1321 1322.. code-block:: typescript 1323 1324 let x: Object[] = [new Int(1), new Int(2)] 1325 1326 // Implicit boxing of primitive int to object Int 1327 let x1: Object[] = [1, 2] 1328 1329 let y: Object[] = [1, "aa"] 1330 1331|CB_SEE| 1332~~~~~~~~ 1333 1334* :ref:`R038` 1335* :ref:`R040` 1336 1337.. _R044: 1338 1339|CB_R| #44: Template literals are not supported 1340----------------------------------------------- 1341 1342|CB_RULE| 1343~~~~~~~~~ 1344 1345Currently, |LANG| does not support template literals. You may use a ``+`` 1346concatenation as a work-around. 1347 1348|CB_BAD| 1349~~~~~~~~ 1350 1351.. code-block:: typescript 1352 1353 const a = 5 1354 const b = 10 1355 console.log(`Fifteen is ${a + b}`) 1356 1357|CB_OK| 1358~~~~~~~ 1359 1360.. code-block:: typescript 1361 1362 const a = 5 1363 const b = 10 1364 1365 // (a + b) is converted to Int and then toString() method is called: 1366 console.log("Fifteen is " + (a + b)) 1367 1368.. _R045: 1369 1370|CB_R| #45: Lambdas require explicit type annotation for parameters 1371------------------------------------------------------------------- 1372 1373|CB_RULE| 1374~~~~~~~~~ 1375 1376Currently, |LANG| requires the types of lambda parameters 1377to be explicitly specified. 1378 1379|CB_BAD| 1380~~~~~~~~ 1381 1382.. code-block:: typescript 1383 1384 let f = (s) => { // type any is assumed 1385 console.log(s) 1386 } 1387 1388|CB_OK| 1389~~~~~~~ 1390 1391Explicit types for lambda parameters are mandatory. 1392 1393.. code-block:: typescript 1394 1395 let f = 1396 (s: string) => { 1397 console.log(s) 1398 } 1399 1400|CB_SEE| 1401~~~~~~~~ 1402 1403* :ref:`R047` 1404 1405.. _R046: 1406 1407|CB_R| #46: Use arrow functions instead of function expressions 1408------------------------------------------------------------------- 1409 1410|CB_RULE| 1411~~~~~~~~~ 1412 1413|LANG| does not support function expressions, use arrow functions instead 1414to be explicitly specified. 1415 1416|CB_BAD| 1417~~~~~~~~ 1418 1419.. code-block:: typescript 1420 1421 let f = function (s: string) { 1422 console.log(s) 1423 } 1424 1425|CB_OK| 1426~~~~~~~ 1427 1428.. code-block:: typescript 1429 1430 let f = (s: string) => { 1431 console.log(s) 1432 } 1433 1434.. _R047: 1435 1436|CB_R| #47: Return type must be specified for lambdas explicitly 1437---------------------------------------------------------------- 1438 1439|CB_RULE| 1440~~~~~~~~~ 1441 1442An explicit return type is mandatory for a lambda expression. 1443 1444|CB_BAD| 1445~~~~~~~~ 1446 1447.. code-block:: typescript 1448 1449 let f = (s: string) => { // return type is implicit 1450 return s.toLowerCase() 1451 } 1452 1453|CB_OK| 1454~~~~~~~ 1455 1456.. code-block:: typescript 1457 1458 let f = (s: string): string => { // return type is explicit 1459 return s.toLowerCase() 1460 } 1461 1462|CB_SEE| 1463~~~~~~~~ 1464 1465* :ref:`R045` 1466 1467.. _R049: 1468 1469|CB_R| #49: Usage of arrow function with type assertions or generics 1470-------------------------------------------------------------------- 1471 1472|CB_BAD| 1473~~~~~~~~ 1474 1475A non-compliant syntax is used. Not a part of the common subset. 1476 1477.. code-block:: typescript 1478 1479 let generic_arrow_func = 1480 <T extends String> (x: T) => { return x } 1481 let type_asserted_function = 1482 <() => boolean> (() => {return true}) 1483 1484 generic_arrow_func(5) // Compile-time error 1485 generic_arrow_func("string") 1486 type_asserted_function() 1487 1488|CB_OK| 1489~~~~~~~ 1490 1491Introduce a new function to replace an arrow function with generics. 1492Explicit types are mandatory, static typing replaces type assertions by design. 1493 1494.. code-block:: typescript 1495 1496 function generic_arrow_func<T extends String>(x: T): T { 1497 return x 1498 } 1499 1500 let type_asserted_func: () => boolean = 1501 (): boolean => {return true} 1502 1503 generic_arrow_func(5) // Compile-time error 1504 generic_arrow_func("string") 1505 1506 type_asserted_func() 1507 1508.. _R050: 1509 1510|CB_R| #50: Class literals are not supported 1511-------------------------------------------- 1512 1513|CB_RULE| 1514~~~~~~~~~ 1515 1516|LANG| does not support class literals. A new named class type must be 1517introduced explicitly. 1518 1519|CB_BAD| 1520~~~~~~~~ 1521 1522.. code-block:: typescript 1523 1524 const Rectangle = class { 1525 constructor(height: number, width: number) { 1526 this.heigth = height 1527 this.width = width 1528 } 1529 1530 heigth 1531 width 1532 } 1533 1534 const rectangle = new Rectangle(0.0, 0.0) 1535 1536|CB_OK| 1537~~~~~~~ 1538 1539.. code-block:: typescript 1540 1541 class Rectangle { 1542 constructor(height: number, width: number) { 1543 this.heigth = height 1544 this.width = width 1545 } 1546 1547 heigth: number 1548 width: number 1549 } 1550 1551 const rectangle = new Rectangle(0.0, 0.0) 1552 1553.. _R051: 1554 1555|CB_R| #51: Classes cannot be specified in ``implements`` clause 1556---------------------------------------------------------------- 1557 1558|CB_RULE| 1559~~~~~~~~~ 1560 1561|LANG| does not allow to specify a class in implements clause. Only interfaces may be specified. 1562 1563|CB_BAD| 1564~~~~~~~~ 1565 1566.. code-block:: typescript 1567 1568 class C { 1569 foo() {} 1570 } 1571 1572 class C1 implements C { 1573 foo() {} 1574 } 1575 1576|CB_OK| 1577~~~~~~~ 1578 1579.. code-block:: typescript 1580 1581 interface C { 1582 foo() 1583 } 1584 1585 class C1 implements C { 1586 foo() {} 1587 } 1588 1589 1590.. _R052: 1591 1592|CB_R| #52: Attempt to access an undefined property is a compile-time error 1593--------------------------------------------------------------------------- 1594 1595|CB_RULE| 1596~~~~~~~~~ 1597 1598|LANG| supports accessing only those class properties that are either declared 1599in the class, or accessible via inheritance. Accessing any other properties is 1600prohibited and causes compile-time errors. 1601 1602|CB_BAD| 1603~~~~~~~~ 1604 1605.. code-block:: typescript 1606 1607 let person = {name: "Bob", isEmployee: true} 1608 1609 let n = typ["name"] 1610 let e = typ["isEmployee"] 1611 let s = typ["office"] // undefined 1612 1613|CB_OK| 1614~~~~~~~ 1615 1616Use proper types to check property existence during compilation. 1617 1618.. code-block:: typescript 1619 1620 class Person { 1621 constructor(name: string, isEmployee: boolean) { 1622 this.name = name 1623 this.isEmployee = isEmployee 1624 } 1625 1626 name: string 1627 isEmployee: boolean 1628 } 1629 1630 let person = new Person("Bob", true) 1631 let n = typ.name 1632 let e = typ.isEmployee 1633 let s = typ.office // Compile-time error 1634 1635|CB_SEE| 1636~~~~~~~~ 1637 1638* :ref:`R001` 1639* :ref:`R002` 1640* :ref:`R059` 1641* :ref:`R060` 1642* :ref:`R066` 1643* :ref:`R105` 1644* :ref:`R109` 1645 1646.. _R053: 1647 1648|CB_R| #53: Only ``as T`` syntax is supported for type casts 1649------------------------------------------------------------ 1650 1651|CB_RULE| 1652~~~~~~~~~ 1653 1654|LANG| supports ``as`` keyword as the only syntax for type casts. 1655Incorrect cast causes a compile-time error or runtime ``ClassCastError``. 1656``<type>`` syntax for type casts is not supported. 1657 1658|CB_BAD| 1659~~~~~~~~ 1660 1661.. code-block:: typescript 1662 1663 class Shape {} 1664 class Circle extends Shape {x: number = 5} 1665 class Square extends Shape {y: string = "a"} 1666 1667 function createShape(): Shape { 1668 return new Circle() 1669 } 1670 1671 let c1 = <Circle> createShape() 1672 1673 let c2 = createShape() as Circle 1674 1675 // No report is provided during compilation 1676 // nor during runtime if cast is wrong: 1677 let c3 = createShape() as Square 1678 console.log(c3.y) // undefined 1679 1680|CB_OK| 1681~~~~~~~ 1682 1683.. code-block:: typescript 1684 1685 class Shape {} 1686 class Circle extends Shape {x: number = 5} 1687 class Square extends Shape {y: string = "a"} 1688 1689 function createShape(): Shape { 1690 return new Circle() 1691 } 1692 1693 let c2 = createShape() as Circle 1694 1695 // ClassCastError during runtime is thrown: 1696 let c3 = createShape() as Square 1697 1698.. _R054: 1699 1700|CB_R| #54: JSX expressions are not supported 1701--------------------------------------------- 1702 1703|CB_RULE| 1704~~~~~~~~~ 1705 1706Do not use JSX since no alternative is provided to rewrite it. 1707 1708.. _R055: 1709 1710|CB_R| #55: Unary operators ``+``, ``-`` and ``~`` work only on numbers 1711----------------------------------------------------------------------- 1712 1713|CB_RULE| 1714~~~~~~~~~ 1715 1716|LANG| allows unary operators to work on numeric types only. A compile-time 1717error occurs if these operators are applied to a non-numeric type. Unlike in 1718|TS|, implicit casting of strings in this context is not supported and must 1719be done explicitly. 1720 1721|CB_BAD| 1722~~~~~~~~ 1723 1724.. code-block:: typescript 1725 1726 let a = +5 // 5 as number 1727 let b = +"5" // 5 as number 1728 let c = -5 // -5 as number 1729 let d = -"5" // -5 as number 1730 let e = ~5 // -6 as number 1731 let f = ~"5" // -6 as number 1732 let g = +"string" // NaN as number 1733 1734|CB_OK| 1735~~~~~~~ 1736 1737.. code-block:: typescript 1738 1739 let a = +5 // 5 as int 1740 let b = +"5" // Compile-time error 1741 let c = -5 // -5 as int 1742 let d = -"5" // Compile-time error 1743 let e = ~5 // -6 as int 1744 let f = ~"5" // Compile-time error 1745 let g = +"string" // Compile-time error 1746 1747|CB_SEE| 1748~~~~~~~~ 1749 1750* :ref:`R055` 1751* :ref:`R057` 1752* :ref:`R061` 1753* :ref:`R062` 1754* :ref:`R063` 1755* :ref:`R064` 1756* :ref:`R067` 1757* :ref:`R068` 1758* :ref:`R078` 1759 1760.. _R056: 1761 1762|CB_R| #56: Unary ``+`` cannot be used for casting to ``number`` 1763---------------------------------------------------------------- 1764 1765|CB_RULE| 1766~~~~~~~~~ 1767 1768|LANG| does not support casting from any type to a numeric type 1769by using the unary ``+`` operator, which can be applied only to 1770numeric types. 1771 1772|CB_BAD| 1773~~~~~~~~ 1774 1775.. code-block:: typescript 1776 1777 function returnTen(): string { 1778 return "-10" 1779 } 1780 1781 function returnString(): string { 1782 return "string" 1783 } 1784 1785 let a = +returnTen() // -10 as number 1786 let b = +returnString() // NaN 1787 1788|CB_OK| 1789~~~~~~~ 1790 1791.. code-block:: typescript 1792 1793 function returnTen(): string { 1794 return "-10" 1795 } 1796 1797 function returnString(): string { 1798 return "string" 1799 } 1800 1801 let a = +returnTen() // Compile-time error 1802 let b = +returnString() // Compile-time error 1803 1804|CB_SEE| 1805~~~~~~~~ 1806 1807* :ref:`R055` 1808* :ref:`R057` 1809* :ref:`R061` 1810* :ref:`R062` 1811* :ref:`R063` 1812* :ref:`R064` 1813* :ref:`R067` 1814* :ref:`R068` 1815* :ref:`R078` 1816 1817.. _R057: 1818 1819|CB_R| #57: ``!`` operator works only on values of the boolean type 1820------------------------------------------------------------------- 1821 1822|CB_RULE| 1823~~~~~~~~~ 1824 1825|LANG| supports using ``!`` operator only for values of the boolean type. 1826Explicit cast from some type to the boolean (or Boolean) is mandatory. 1827Implicit casts are prohibited and cause compile-time errors. 1828 1829|CB_BAD| 1830~~~~~~~~ 1831 1832.. code-block:: typescript 1833 1834 let a = !true // false 1835 let b = !"true" // false 1836 let c = !"rnd_str" // false 1837 let d = !"false" // false 1838 let e = !5 // false 1839 let f = !0 // true 1840 1841|CB_OK| 1842~~~~~~~ 1843 1844.. code-block:: typescript 1845 1846 let a = !true // false 1847 let b = !"true" // Compile-time error 1848 let c = !"false" // Compile-time error 1849 let d = !"rnd_str" // Compile-time error 1850 let e = !5 // Compile-time error 1851 let f = !0 // Compile-time error 1852 1853|CB_SEE| 1854~~~~~~~~ 1855 1856* :ref:`R055` 1857* :ref:`R056` 1858* :ref:`R061` 1859* :ref:`R062` 1860* :ref:`R063` 1861* :ref:`R064` 1862* :ref:`R067` 1863* :ref:`R068` 1864* :ref:`R078` 1865 1866.. _R059: 1867 1868|CB_R| #59: ``delete`` operator is not supported 1869------------------------------------------------ 1870 1871|CB_RULE| 1872~~~~~~~~~ 1873 1874|LANG| assumes that object layout is known at compile time and cannot be 1875changed at runtime. Thus the operation of deleting a property makes no sense. 1876 1877|CB_BAD| 1878~~~~~~~~ 1879 1880.. code-block:: typescript 1881 1882 class Point { 1883 x?: number = 0.0 1884 y?: number = 0.0 1885 } 1886 1887 let p = new Point() 1888 delete p.y 1889 1890|CB_OK| 1891~~~~~~~ 1892 1893.. code-block:: typescript 1894 1895 // To mimic the original semantics, you may declare a nullable type 1896 // and assign null to mark value absence: 1897 1898 class Point { 1899 x: number | null 1900 y: number | null 1901 } 1902 1903 let p = new Point() 1904 p.y = null 1905 1906|CB_SEE| 1907~~~~~~~~ 1908 1909* :ref:`R001` 1910* :ref:`R002` 1911* :ref:`R052` 1912* :ref:`R060` 1913* :ref:`R066` 1914* :ref:`R105` 1915* :ref:`R109` 1916 1917.. _R060: 1918 1919|CB_R| #60: ``typeof`` is allowed only in expression contexts 1920------------------------------------------------------------- 1921 1922|CB_RULE| 1923~~~~~~~~~ 1924 1925|LANG| supports ``typeof`` operator only in the expression context. 1926Type notation with ``typeof`` is not supported. 1927 1928|CB_BAD| 1929~~~~~~~~ 1930 1931.. code-block:: typescript 1932 1933 let n1 = 42 1934 let s1 = "foo" 1935 console.log(typeof n1) // "number" 1936 console.log(typeof s1) // "string" 1937 let n2: typeof n1 1938 let s2: typeof s1 1939 1940|CB_OK| 1941~~~~~~~ 1942 1943.. code-block:: typescript 1944 1945 let n1 = 42 1946 let s1 = "foo" 1947 console.log(typeof n1) // "number" 1948 console.log(typeof s1) // "string" 1949 let n2: number 1950 let s2: string 1951 1952|CB_SEE| 1953~~~~~~~~ 1954 1955* :ref:`R001` 1956* :ref:`R002` 1957* :ref:`R052` 1958* :ref:`R059` 1959* :ref:`R066` 1960* :ref:`R105` 1961* :ref:`R109` 1962 1963.. _R061: 1964 1965|CB_R| #61: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types 1966----------------------------------------------------------------------------------------------------------------------------------- 1967 1968|CB_RULE| 1969~~~~~~~~~ 1970 1971|LANG| allows applying binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, 1972``>>``, ``>>>``, ``&``, ``^`` and ``|`` only to values of numeric types. 1973Implicit casts from other types to numeric types are prohibited and cause 1974compile-time errors. 1975 1976|CB_BAD| 1977~~~~~~~~ 1978 1979.. code-block:: typescript 1980 1981 let a = (5 & 5) // 5 1982 let b = (5.5 & 5.5) // 5, not 5.5 1983 let c = (5 | 5) // 5 1984 let d = (5.5 | 5.5) // 5, not 5.5 1985 1986 enum Direction { 1987 Up = -1, 1988 Down 1989 } 1990 let e = Direction.Up >> 1 // -1 1991 let f = Direction.Up >>> 1 // 2147483647 1992 1993 let g = ("10" as any) << 1 // 20 1994 let h = ("str" as any) << 1 // 0 1995 1996 let i = 10 * 5 1997 let j = 10 / 5 1998 let k = 10 % 5 1999 let l = 10 - 5 2000 2001|CB_OK| 2002~~~~~~~ 2003 2004.. code-block:: typescript 2005 2006 let a = (5 & 5) // 5 2007 let b = (5.5 & 5.5) // Compile-time error 2008 let c = (5 | 5) // 5 2009 let d = (5.5 | 5.5) // Compile-time error 2010 2011 enum Direction { 2012 Up, // TBD: explicit start value 2013 Down 2014 } 2015 2016 let e = Direction.Up >> 1 // 0 2017 let f = Direction.Up >>> 1 // 0 2018 2019 let i = 10 * 5 2020 let j = 10 / 5 2021 let k = 10 % 5 2022 let l = 10 - 5 2023 2024|CB_SEE| 2025~~~~~~~~ 2026 2027* :ref:`R055` 2028* :ref:`R056` 2029* :ref:`R057` 2030* :ref:`R062` 2031* :ref:`R063` 2032* :ref:`R064` 2033* :ref:`R067` 2034* :ref:`R068` 2035* :ref:`R078` 2036 2037.. _R062: 2038 2039|CB_R| #62: Binary operators ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on integral numeric types 2040---------------------------------------------------------------------------------------------------------------- 2041 2042|CB_RULE| 2043~~~~~~~~~ 2044 2045|LANG| expects an explicit cast to an integral type for logical binary 2046operations. Implicit casts are prohibited and cause compile-time errors. 2047 2048|CB_BAD| 2049~~~~~~~~ 2050 2051.. code-block:: typescript 2052 2053 let b = (5.5 & 5.5) // 5, not 5.5 2054 let d = (5.5 | 5.5) // 5, not 5.5 2055 2056 let g = ("10" as any) << 1 // 20 2057 let h = ("str" as any) << 1 // 0 2058 2059|CB_OK| 2060~~~~~~~ 2061 2062.. code-block:: typescript 2063 2064 let b = (5.5 & 5.5) // Compile-time error 2065 let d = (5.5 | 5.5) // Compile-time error 2066 2067|CB_SEE| 2068~~~~~~~~ 2069 2070* :ref:`R055` 2071* :ref:`R056` 2072* :ref:`R057` 2073* :ref:`R061` 2074* :ref:`R063` 2075* :ref:`R064` 2076* :ref:`R067` 2077* :ref:`R068` 2078* :ref:`R078` 2079 2080.. _R063: 2081 2082|CB_R| #63: Binary ``+`` operator supports implicit casts only for numbers and strings 2083-------------------------------------------------------------------------------------- 2084 2085|CB_RULE| 2086~~~~~~~~~ 2087 2088|LANG| supports implicit casts for ``+`` only for strings and numbers. 2089Elsewhere, any form of an explicit cast to string is required. 2090 2091|CB_BAD| 2092~~~~~~~~ 2093 2094.. code-block:: typescript 2095 2096 enum E { E1, E2 } 2097 2098 let a = 10 + 32 // 42 2099 let b = E.E1 + 10 // 10 2100 let c = 10 + "5" // "105" 2101 2102 let d = "5" + E.E2 // "51" 2103 let e = "Hello, " + "world!" // "Hello, world!" 2104 let f = "string" + true // "stringtrue" 2105 2106 let g = (new Object()) + "string" // "[object Object]string" 2107 2108|CB_OK| 2109~~~~~~~ 2110 2111.. code-block:: typescript 2112 2113 enum E { E1, E2 } 2114 2115 let a = 10 + 32 // 42 2116 let b = E.E1 + 10 // 10 2117 let c = 10 + "5" // "105" 2118 2119 let d = "5" + E.E2 // "51" 2120 let e = "Hello, " + "world!" // "Hello, world!" 2121 let f = "string" + true // "stringtrue" 2122 2123 let g = (new Object()).toString() + "string" 2124 2125|CB_SEE| 2126~~~~~~~~ 2127 2128* :ref:`R055` 2129* :ref:`R056` 2130* :ref:`R057` 2131* :ref:`R061` 2132* :ref:`R062` 2133* :ref:`R064` 2134* :ref:`R067` 2135* :ref:`R068` 2136* :ref:`R078` 2137 2138.. _R064: 2139 2140|CB_R| #64: Binary ``+`` operator requires explicit casts for non-numbers and non-strings 2141----------------------------------------------------------------------------------------- 2142 2143|CB_RULE| 2144~~~~~~~~~ 2145 2146|LANG| supports implicit casts for ``+`` only for strings and numbers. 2147Elsewhere, any form of an explicit cast to string is required. 2148 2149|CB_BAD| 2150~~~~~~~~ 2151 2152.. code-block:: typescript 2153 2154 // "[object Object][object Object]" 2155 let o = ({x: 5} as any) + {y: 6} 2156 2157|CB_OK| 2158~~~~~~~ 2159 2160.. code-block:: typescript 2161 2162 let o = (new Object()).toString() + new Int(5) // "5" 2163 2164|CB_SEE| 2165~~~~~~~~ 2166 2167* :ref:`R055` 2168* :ref:`R056` 2169* :ref:`R057` 2170* :ref:`R061` 2171* :ref:`R062` 2172* :ref:`R063` 2173* :ref:`R067` 2174* :ref:`R068` 2175* :ref:`R078` 2176 2177|CB_R| #65: ``instanceof`` operator is partially supported 2178---------------------------------------------------------- 2179 2180|CB_RULE| 2181~~~~~~~~~ 2182 2183In |TS|, the left-hand side of an ``instanceof`` expression must be of type 2184``any``, an object type or a type parameter, otherwise the result is ``false``. 2185In |LANG|, the left-hand side expression may be of any reference type, otherwise 2186a compile-time error occurs. In addition, the left operand in |LANG| cannot be 2187a type. 2188 2189|CB_BAD| 2190~~~~~~~~ 2191 2192.. code-block:: typescript 2193 2194 class X {} 2195 2196 let a = (new X()) instanceof Object // true 2197 let b = (new X()) instanceof X // true 2198 // left operand is a type: 2199 let c = X instanceof Object // true 2200 let d = X instanceof X // false 2201 2202 // left operand is not of type any 2203 let e = (5.0 as Number) instanceof Number // false 2204 2205|CB_OK| 2206~~~~~~~ 2207 2208.. code-block:: typescript 2209 2210 class X {} 2211 2212 let a = (new X()) instanceof Object // true 2213 let b = (new X()) instanceof X // true 2214 // left operand is a type: 2215 let c = X instanceof Object // Compile-time error 2216 let d = X instanceof X // Compile-time error 2217 2218 // left operand may be of any reference type, like number 2219 let e = (5.0 as Number) instanceof Number // true 2220 2221.. _R066: 2222 2223|CB_R| #66: ``in`` operator is not supported 2224-------------------------------------------- 2225 2226|CB_RULE| 2227~~~~~~~~~ 2228 2229|LANG| does not support the ``in`` operator. However, this operator makes 2230little sense since the object layout is known at compile time and cannot 2231be modified at runtime. Use ``instanceof`` as a work-around if you still need 2232to check whether certain class members exist. 2233 2234|CB_BAD| 2235~~~~~~~~ 2236 2237.. code-block:: typescript 2238 2239 class Person { 2240 name: string = "" 2241 } 2242 let p = new Person() 2243 2244 let b = "name" in p // true 2245 2246|CB_OK| 2247~~~~~~~ 2248 2249.. code-block:: typescript 2250 2251 class Person { 2252 name: string = "" 2253 } 2254 let p = new Person() 2255 2256 let b = p instanceof Person // true, and "name" is guaranteed to be present 2257 2258|CB_SEE| 2259~~~~~~~~ 2260 2261* :ref:`R001` 2262* :ref:`R002` 2263* :ref:`R052` 2264* :ref:`R059` 2265* :ref:`R060` 2266* :ref:`R105` 2267* :ref:`R109` 2268 2269.. _R067: 2270 2271|CB_R| #67: Operators ``&&`` and ``||`` work on values of the boolean type only 2272------------------------------------------------------------------------------- 2273 2274|CB_RULE| 2275~~~~~~~~~ 2276 2277|LANG| supports using ``&&`` and ``||`` operators only for the values of the 2278boolean type. Explicit cast from some type to the boolean (or Boolean) is 2279mandatory. Implicit casts are prohibited and cause compile-time errors. 2280 2281|CB_BAD| 2282~~~~~~~~ 2283 2284.. code-block:: typescript 2285 2286 let a = true && false // false 2287 let b = 5 || 0 // 5 2288 let c = 5 && 0 // 0 2289 let d = "" && 5 // "" 2290 let e = "" || "abcd" // "abcd" 2291 2292|CB_OK| 2293~~~~~~~ 2294 2295.. code-block:: typescript 2296 2297 let a = true && false // false 2298 let b = 5 || 0 // Compile-time error 2299 let c = 5 && 0 // Compile-time error 2300 let d = "" && 5 // Compile-time error 2301 let e = "" || "abcd" // Compile-time error 2302 2303|CB_SEE| 2304~~~~~~~~ 2305 2306* :ref:`R055` 2307* :ref:`R056` 2308* :ref:`R057` 2309* :ref:`R061` 2310* :ref:`R062` 2311* :ref:`R063` 2312* :ref:`R064` 2313* :ref:`R068` 2314* :ref:`R078` 2315 2316.. _R068: 2317 2318|CB_R| #68: Using of ``&&`` and ``||`` on non-boolean types is not supported 2319---------------------------------------------------------------------------- 2320 2321|CB_RULE| 2322~~~~~~~~~ 2323 2324|LANG| supports the usage of ``&&`` and ``||`` operators only for the values 2325of the boolean type. Explicit cast from some type to the boolean (or Boolean) 2326is mandatory. Implicit casts are prohibited and cause compile-time errors. 2327 2328|CB_BAD| 2329~~~~~~~~ 2330 2331.. code-block:: typescript 2332 2333 let a = true && false // false 2334 let b = 5 || 0 // 5 2335 let c = 5 && 0 // 0 2336 let d = "" && 5 // "" 2337 let e = "" || "abcd" // "abcd" 2338 2339|CB_OK| 2340~~~~~~~ 2341 2342.. code-block:: typescript 2343 2344 let a = true && false // false 2345 let b = 5 || 0 // Compile-time error 2346 let c = 5 && 0 // Compile-time error 2347 let d = "" && 5 // Compile-time error 2348 let e = "" || "abcd" // Compile-time error 2349 2350|CB_SEE| 2351~~~~~~~~ 2352 2353* :ref:`R055` 2354* :ref:`R056` 2355* :ref:`R057` 2356* :ref:`R061` 2357* :ref:`R062` 2358* :ref:`R063` 2359* :ref:`R064` 2360* :ref:`R067` 2361* :ref:`R078` 2362 2363.. _R069: 2364 2365|CB_R| #69: Destructuring assignment is not supported 2366----------------------------------------------------- 2367 2368|CB_RULE| 2369~~~~~~~~~ 2370 2371|LANG| does not support destructuring assignment. Other idioms (e.g., 2372using a temporary variable, where applicable) can be used for replacement. 2373 2374|CB_BAD| 2375~~~~~~~~ 2376 2377.. code-block:: typescript 2378 2379 let [one, two] = [1, 2] 2380 [one, two] = [two, one] 2381 2382 let head, tail 2383 [head, ...tail] = [1, 2, 3, 4] 2384 2385|CB_OK| 2386~~~~~~~ 2387 2388.. code-block:: typescript 2389 2390 let arr: number[] = [1, 2] 2391 let one = arr[0] 2392 let two = arr[1] 2393 2394 let tmp = one 2395 one = two 2396 two = tmp 2397 2398 let data: Number[] = [1,2,3,4] 2399 let head = data[0] 2400 let tail = new Number[data.length - 1] 2401 for (let i = 1; i < data.length; ++i) { 2402 tail[i-1] = data[i] 2403 } 2404 2405.. _R071: 2406 2407|CB_R| #71: The comma operator ``,`` is supported only in ``for`` loops 2408----------------------------------------------------------------------- 2409 2410|CB_RULE| 2411~~~~~~~~~ 2412 2413|LANG| supports the comma operator ``,`` only in ``for`` loops. Otherwise, 2414it is useless as it makes the execution order harder to understand. 2415 2416|CB_BAD| 2417~~~~~~~~ 2418 2419.. code-block:: typescript 2420 2421 for (let i = 0, j = 0; i < 10; ++i, j += 2) { 2422 console.log(i, j) 2423 } 2424 2425 let x = 0 2426 x = (++x, x++) // 1 2427 2428|CB_OK| 2429~~~~~~~ 2430 2431.. code-block:: typescript 2432 2433 for (let i = 0, j = 0; i < 10; ++i, j += 2) { 2434 console.log(i, j) 2435 } 2436 2437 // Use explicit execution order instead of the comma operator: 2438 let x = 0 2439 ++x 2440 x = x++ 2441 2442.. _R073: 2443 2444|CB_R| #74: Destructuring variable declarations are not supported 2445----------------------------------------------------------------- 2446 2447|CB_RULE| 2448~~~~~~~~~ 2449 2450|LANG| does not support destructuring variable declarations. This is a dynamic 2451feature relying on structural compatibility. In addition, names in destructuring 2452declarations must be equal to properties within destructured classes. 2453 2454|CB_BAD| 2455~~~~~~~~ 2456 2457.. code:: typescript 2458 2459 class Point { 2460 x: number = 0.0 2461 y: number = 0.0 2462 } 2463 2464 function returnZeroPoint(): Point { 2465 return new Point() 2466 } 2467 2468 let {x, y} = returnZeroPoint() 2469 2470|CB_OK| 2471~~~~~~~ 2472 2473.. code:: typescript 2474 2475 class Point { 2476 x: number = 0.0 2477 y: number = 0.0 2478 } 2479 2480 function returnZeroPoint(): Point { 2481 return new Point() 2482 } 2483 2484 // Create an intermediate object and work with it field by field 2485 // without name restrictions: 2486 let zp = returnZeroPoint() 2487 let x = zp.x 2488 let y = zp.y 2489 2490.. _R076: 2491 2492|CB_R| #76: Inference of implied types is not supported 2493------------------------------------------------------- 2494 2495|CB_RULE| 2496~~~~~~~~~ 2497 2498Currently, |LANG| does not support inference of implied types. Use explicit 2499type notation instead. Use ``Object[]`` if you need containers that hold 2500data of mixed types. 2501 2502|CB_BAD| 2503~~~~~~~~ 2504 2505.. code-block:: typescript 2506 2507 let [a, b, c] = [1, "hello", true] 2508 2509|CB_OK| 2510~~~~~~~ 2511 2512.. code-block:: typescript 2513 2514 let a = 1 2515 let b = "hello" 2516 let c = true 2517 2518 let arr: Object[] = [1, "hello", true] 2519 let a1 = arr[0] 2520 let b1 = arr[1] 2521 let c1 = arr[2] 2522 2523.. _R078: 2524 2525|CB_R| #78: Implicit casts to the boolean are not supported in ``if``, ``do`` and ``while`` 2526------------------------------------------------------------------------------------------- 2527 2528|CB_RULE| 2529~~~~~~~~~ 2530 2531|LANG| supports only values of the boolean type in ``if``, ``do`` and ``while`` 2532statements. Implicit casts from other types to the boolean are prohibited and 2533cause compile-time errors. 2534 2535|CB_BAD| 2536~~~~~~~~ 2537 2538.. code-block:: typescript 2539 2540 if (true) {} 2541 do {} while (false) 2542 2543 let a = new Boolean(true) 2544 if (a) {} 2545 do {break} while (a) 2546 while (a) {break} 2547 2548 let b = 42 2549 if (b) {} 2550 do {break} while (b) 2551 while (b) {break} 2552 2553 let c = "str" 2554 if (c) {} 2555 do {break} while (c) 2556 while (c) {break} 2557 2558 let d = new Object() 2559 if (d) {} 2560 do {break} while (d) 2561 while (d) {break} 2562 2563|CB_OK| 2564~~~~~~~ 2565 2566.. code-block:: typescript 2567 2568 if (true) {} 2569 do {} while (false) 2570 2571 let a = new Boolean(true) 2572 if (a) {} 2573 do {break} while (a) 2574 while (a) {break} 2575 2576 let b = 42 2577 if (b != 0) {} 2578 do {break} while (b != 0) 2579 while (b != 0) {break} 2580 2581 let c = "str" 2582 if (c.length != 0) {} 2583 do {break} while (c.length != 0) 2584 while (c.length != 0) {break} 2585 2586 let d = new Object() 2587 if (d != null) {} 2588 do {break} while (d != null) 2589 while (d != null) {break} 2590 2591|CB_SEE| 2592~~~~~~~~ 2593 2594* :ref:`R055` 2595* :ref:`R056` 2596* :ref:`R057` 2597* :ref:`R061` 2598* :ref:`R062` 2599* :ref:`R063` 2600* :ref:`R064` 2601* :ref:`R067` 2602* :ref:`R068` 2603 2604.. _R079: 2605 2606|CB_R| #79: Type annotation in catch clause is not supported 2607------------------------------------------------------------ 2608 2609|CB_RULE| 2610~~~~~~~~~ 2611 2612In |TS| catch clause variable type annotation must be ``any`` or ``unknown`` if specified. 2613As |LANG| does not support these types, a type annotation should be omitted. 2614 2615|CB_BAD| 2616~~~~~~~~ 2617 2618.. code-block:: typescript 2619 2620 try { 2621 // some code 2622 } 2623 catch (a: unknown) {} 2624 2625|CB_OK| 2626~~~~~~~ 2627 2628.. code:: typescript 2629 2630 try { 2631 // some code 2632 } 2633 catch (a) {} 2634 2635|CB_SEE| 2636~~~~~~~~ 2637 2638* :ref:`R087` 2639 2640.. _R080: 2641 2642|CB_R| #80: ``for .. in`` is not supported 2643------------------------------------------ 2644 2645|CB_RULE| 2646~~~~~~~~~ 2647 2648|LANG| does not support the iteration over object contents by the 2649``for .. in`` loop. For objects, iteration over properties at runtime is 2650considered redundant because object layout is known at compile time and cannot 2651change at runtime. For arrays, you can iterate with the regular ``for`` loop. 2652 2653|CB_BAD| 2654~~~~~~~~ 2655 2656.. code-block:: typescript 2657 2658 let a: number[] = [1.0, 2.0, 3.0] 2659 for (let i in a) { 2660 console.log(a[i]) 2661 } 2662 2663|CB_OK| 2664~~~~~~~ 2665 2666.. code:: typescript 2667 2668 let a: number[] = [1.0, 2.0, 3.0] 2669 for (let i = 0; i < a.length; ++i) { 2670 console.log(a[i]) 2671 } 2672 2673|CB_SEE| 2674~~~~~~~~ 2675 2676* :ref:`R081` 2677* :ref:`R082` 2678 2679.. _R081: 2680 2681|CB_R| #81: Iterable interfaces are not supported 2682------------------------------------------------- 2683 2684|CB_RULE| 2685~~~~~~~~~ 2686 2687|LANG| does not support the ``Symbol`` API, ``Symbol.iterator`` and 2688eventually iterable interfaces. Use arrays and library-level containers to 2689iterate over data. 2690 2691|CB_SEE| 2692~~~~~~~~ 2693 2694* :ref:`R002` 2695* :ref:`R080` 2696* :ref:`R082` 2697 2698.. _R082: 2699 2700|CB_R| ``for-of`` is supported only for arrays, strings, sets, maps and classes derived from them 2701------------------------------------------------------------------------------------------------- 2702 2703|CB_RULE| 2704~~~~~~~~~ 2705 2706|LANG| supports the iteration over arrays, strings, sets, maps and classes 2707derived from them by the ``for .. of`` loop, but does not support the 2708iteration of objects content. All typed arrays from the standard 2709library (for example, ``Int32Array``) are also supported. 2710 2711|CB_BAD| 2712~~~~~~~~ 2713 2714.. code-block:: typescript 2715 class A { 2716 prop1: number; 2717 prop2: number; 2718 } 2719 let a = new A() 2720 for (let prop of a) { 2721 console.log(prop) 2722 } 2723 2724|CB_OK| 2725~~~~~~~ 2726 2727.. code-block:: typescript 2728 2729 let a = new Set<number>([1, 2, 3]) 2730 for (let n of a) { 2731 console.log(n) 2732 } 2733|CB_SEE| 2734~~~~~~~~ 2735 2736* :ref:`R080` 2737* :ref:`R081` 2738 2739.. _R083: 2740 2741|CB_R| #83: Mapped type expression is not supported 2742--------------------------------------------------- 2743 2744|CB_RULE| 2745~~~~~~~~~ 2746 2747|LANG| does not support mapped types. Use other language idioms and regular classes 2748to achieve the same behaviour. 2749 2750|CB_BAD| 2751~~~~~~~~ 2752 2753.. code-block:: typescript 2754 2755 type OptionsFlags<Type> = { 2756 [Property in keyof Type]: boolean; 2757 } 2758 2759.. _R084: 2760 2761|CB_R| #84: ``with`` statement is not supported 2762----------------------------------------------- 2763 2764|CB_RULE| 2765~~~~~~~~~ 2766 2767|LANG| does not support the ``with`` statement. Use other language idioms 2768(including fully qualified names of functions) to achieve the same behaviour. 2769 2770.. _R085: 2771 2772|CB_R| #85: Values computed at runtime are not supported in ``case`` statements 2773------------------------------------------------------------------------------- 2774 2775|CB_RULE| 2776~~~~~~~~~ 2777 2778|LANG| supports ``case`` statements that contain only compile-time values. 2779Use ``if`` statements as an alternative. 2780 2781|CB_BAD| 2782~~~~~~~~ 2783 2784.. code-block:: typescript 2785 2786 let x = 2 2787 let y = 3 2788 switch (x) { 2789 case 1: 2790 console.log(1) 2791 break 2792 case 2: 2793 console.log(2) 2794 break 2795 case y: 2796 console.log(y) 2797 break 2798 default: 2799 console.log("other") 2800 } 2801 2802|CB_OK| 2803~~~~~~~ 2804 2805.. code-block:: typescript 2806 2807 let x = 2 2808 switch (x) { 2809 case 1: 2810 console.log(1) 2811 break 2812 case 2: 2813 console.log(2) 2814 break 2815 case 3: 2816 console.log(3) 2817 break 2818 default: 2819 console.log("other") 2820 } 2821 2822|CB_SEE| 2823~~~~~~~~ 2824 2825* :ref:`R112` 2826 2827.. _R086: 2828 2829|CB_R| #86: ``switch`` statements cannot accept values of arbitrary types 2830------------------------------------------------------------------------- 2831 2832|CB_RULE| 2833~~~~~~~~~ 2834 2835|LANG| supports the values of the types ``char``, ``byte``, ``short``, ``int``, 2836``long``, ``Char``, ``Byte``, ``Short``, ``Int``, ``Long``, ``String`` or 2837``enum`` in ``switch`` statements. Use ``if`` statements in other cases. 2838 2839|CB_BAD| 2840~~~~~~~~ 2841 2842.. code-block:: typescript 2843 2844 class Point { 2845 x: number = 0 2846 y: number = 0 2847 } 2848 2849 let a = new Point() 2850 2851 switch (a) { 2852 case null: break; 2853 default: console.log("not null") 2854 } 2855 2856|CB_OK| 2857~~~~~~~ 2858 2859.. code-block:: typescript 2860 2861 class Point { 2862 x: number = 0 2863 y: number = 0 2864 } 2865 2866 let a = new Point() 2867 2868 if (a != null) { 2869 console.log("not null") 2870 } 2871 2872.. _R087: 2873 2874|CB_R| #87: ``throw`` statements cannot accept values of arbitrary types 2875------------------------------------------------------------------------ 2876 2877|CB_RULE| 2878~~~~~~~~~ 2879 2880|LANG| supports throwing only objects of the class ``Error`` or any 2881derived class. Throwing an arbitrary type (i.e., a ``number`` or ``string``) 2882is prohibited. 2883 2884|CB_BAD| 2885~~~~~~~~ 2886 2887.. code-block:: typescript 2888 2889 throw 4 2890 throw "" 2891 throw new Error() 2892 2893|CB_OK| 2894~~~~~~~ 2895 2896.. code-block:: typescript 2897 2898 throw new Error() 2899 2900.. _R088: 2901 2902|CB_R| #88: Each overloaded function should have its body 2903--------------------------------------------------------- 2904 2905|CB_RULE| 2906~~~~~~~~~ 2907 2908|LANG| does not support the |TS| style of overloading signatures with one 2909function body. Define each overloading function with its own body instead of 2910one body for a list of signatures. 2911 2912|CB_BAD| 2913~~~~~~~~ 2914 2915.. code:: typescript 2916 2917 function add(x: number, y: number): number 2918 function add(x: string, y: string): string 2919 function add(x: any, y: any): any { 2920 return x + y 2921 } 2922 2923 console.log(add(2, 3)) // returns 5 2924 console.log(add("hello", "world")) // returns "helloworld" 2925 2926|CB_OK| 2927~~~~~~~ 2928 2929.. code:: typescript 2930 2931 function add(x: number, y: number): number { 2932 return x + y 2933 } 2934 2935 function add(x: string, y: string): string { 2936 return x + y 2937 } 2938 2939 function main() { 2940 console.log(add(2, 3)) // returns 5 2941 console.log(add("hello", "world")) // returns "helloworld" 2942 } 2943 2944|CB_SEE| 2945~~~~~~~~ 2946 2947* :ref:`R089` 2948 2949.. _R089: 2950 2951|CB_R| #89: Each overloaded function with optional parameters should have its body 2952---------------------------------------------------------------------------------- 2953 2954|CB_RULE| 2955~~~~~~~~~ 2956 2957|LANG| does not support the |TS| style of overloading signatures with one 2958function body. Write a separate body for each overloaded signature instead of 2959an optional parameter like `value?` for a single body in |TS|. 2960 2961|CB_BAD| 2962~~~~~~~~ 2963 2964.. code:: typescript 2965 2966 function foo(name: string): number 2967 function foo(name: string, value: string): Accessor 2968 function foo(name: any, value?: string): any { 2969 // one body here 2970 } 2971 2972|CB_OK| 2973~~~~~~~ 2974 2975.. code:: typescript 2976 2977 function foo(name: string): string { 2978 return name 2979 } 2980 2981 function foo(name: string, value: string): Accessor { 2982 return new Accessor() 2983 } 2984 2985|CB_SEE| 2986~~~~~~~~ 2987 2988* :ref:`R088` 2989 2990.. _R090: 2991 2992|CB_R| #90: Function must have explicit return type 2993--------------------------------------------------- 2994 2995|CB_RULE| 2996~~~~~~~~~ 2997 2998|LANG| requires all functions to have explicit return types. For corner cases, 2999use `Object` when it is difficult to determine the return type. 3000 3001|CB_BAD| 3002~~~~~~~~ 3003 3004.. code-block:: typescript 3005 3006 function f(x: number) { 3007 if (x <= 0) { 3008 return x 3009 } 3010 return g(x) 3011 } 3012 3013 function g(x: number) { 3014 return f(x - 1) 3015 } 3016 3017 function doOperation(x: number, y: number) { 3018 return x + y 3019 } 3020 3021 console.log(f(10)) 3022 console.log(doOperation(2, 3)) 3023 3024|CB_OK| 3025~~~~~~~ 3026 3027.. code-block:: typescript 3028 3029 function f(x: number): Object { 3030 if (x <= 0) { 3031 return x 3032 } 3033 return g(x) 3034 } 3035 3036 function g(x: number): Object { 3037 return f(x - 1) 3038 } 3039 3040 function doOperation(x: number, y: number): Object { 3041 let z = x + y 3042 return z 3043 } 3044 3045 function main(): void { 3046 console.log(f(-10) as number) // returns -10 3047 console.log(doOperation(2, 3)) // returns 5 3048 } 3049 3050|CB_R| #91: Destructuring parameter declarations are not supported 3051------------------------------------------------------------------ 3052 3053|CB_RULE| 3054~~~~~~~~~ 3055 3056|LANG| requires that parameters must be passed directly to the function, and 3057local names must be assigned manually. 3058 3059|CB_BAD| 3060~~~~~~~~ 3061 3062.. code:: typescript 3063 3064 function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) { 3065 console.log(text) 3066 console.log(x) 3067 console.log(y) 3068 console.log(bold) 3069 } 3070 3071 drawText({ text: "Hello, world!", location: [100, 50], bold: true }) 3072 3073|CB_OK| 3074~~~~~~~ 3075 3076.. code:: typescript 3077 3078 function drawText(text: String, location: number[], bold: boolean) { 3079 let x = location[0] 3080 let y = location[1] 3081 console.log(text) 3082 console.log(x) 3083 console.log(y) 3084 console.log(bold) 3085 } 3086 3087 function main() { 3088 drawText("Hello, world!", [100, 50], true) 3089 } 3090 3091.. _R092: 3092 3093|CB_R| #92: Nested functions are not supported 3094---------------------------------------------- 3095 3096|CB_RULE| 3097~~~~~~~~~ 3098 3099|LANG| does not support nested functions. Use lambdas instead. 3100 3101|CB_BAD| 3102~~~~~~~~ 3103 3104.. code-block:: typescript 3105 3106 function addNum(a: number, b: number): void { 3107 3108 // nested function: 3109 function logToConsole(message: String): void { 3110 console.log(message) 3111 } 3112 3113 let result = a + b 3114 3115 // Invoking the nested function: 3116 logToConsole("result is " + result) 3117 } 3118 3119|CB_OK| 3120~~~~~~~ 3121 3122.. code-block:: typescript 3123 3124 function addNum(a: number, b: number): void { 3125 3126 // Use lambda instead of a nested function: 3127 let logToConsole: (message: String): void = (message: String): void => { 3128 console.println(message) 3129 } 3130 3131 let result = a + b 3132 3133 logToConsole("result is " + result) 3134 } 3135 3136.. _R093: 3137 3138|CB_R| #93: Using ``this`` inside stand-alone functions is not supported 3139------------------------------------------------------------------------ 3140 3141|CB_RULE| 3142~~~~~~~~~ 3143 3144|LANG| does not support the usage of ``this`` inside stand-alone functions. 3145``this`` can be used in methods only. 3146 3147|CB_BAD| 3148~~~~~~~~ 3149 3150.. code-block:: typescript 3151 3152 function foo(i: number) { 3153 this.count = i 3154 } 3155 3156 class A { 3157 count: number = 1 3158 m = foo 3159 } 3160 3161 let a = new A() 3162 console.log(a.count) // prints "1" 3163 a.m(2) 3164 console.log(a.count) // prints "2" 3165 3166 3167|CB_OK| 3168~~~~~~~ 3169 3170.. code-block:: typescript 3171 3172 class A { 3173 count: number = 1 3174 m(i: number): void { 3175 this.count = i 3176 } 3177 } 3178 3179 function main(): void { 3180 let a = new A() 3181 console.log(a.count) // prints "1" 3182 a.m(2) 3183 console.log(a.count) // prints "2" 3184 } 3185 3186.. _R094: 3187 3188|CB_R| #94: Generator functions are not supported 3189------------------------------------------------- 3190 3191|CB_RULE| 3192~~~~~~~~~ 3193 3194Currently, |LANG| does not support generator functions. 3195Use the ``async`` / ``await`` mechanism for multitasking. 3196 3197|CB_BAD| 3198~~~~~~~~ 3199 3200.. code-block:: typescript 3201 3202 function* counter(start: number, end: number) { 3203 for (let i = start; i <= end; i++) { 3204 yield i 3205 } 3206 } 3207 3208 for (let num of counter(1, 5)) { 3209 console.log(num) 3210 } 3211 3212|CB_OK| 3213~~~~~~~ 3214 3215.. code-block:: typescript 3216 3217 for (let i = 1; i <= 5; ++i) { 3218 console.log(i) 3219 } 3220 3221.. _R095: 3222 3223|CB_R| #95: Asynchronous functions are partially supported 3224---------------------------------------------------------- 3225 3226|CB_RULE| 3227~~~~~~~~~ 3228 3229|LANG| partially supports asynchronous functions. 3230Using the ``launch`` mechanism (|LANG| extension to |TS|) 3231is recommended for multitasking. 3232 3233|CB_BAD| 3234~~~~~~~~ 3235 3236.. code-block:: typescript 3237 3238 async function sum(numbers: number[]): Promise<number> { 3239 let sum = 0 3240 for (let num of numbers) { 3241 sum += await num 3242 } 3243 return sum 3244 } 3245 3246 ... 3247 const result = await sum(5, 10) 3248 ... 3249 3250|CB_OK| 3251~~~~~~~ 3252 3253.. code-block:: typescript 3254 3255 function sum(numbers: number[]): number { 3256 let sum = 0 3257 for (let i = 0; i < numbers.length; ++i) { 3258 sum += numbers[i] 3259 } 3260 return sum 3261 } 3262 3263 ... 3264 const result = launch sum(5, 10) // `result` will be of type `Promise<number>` 3265 ... 3266 3267NOT recommended: 3268 3269.. code-block:: typescript 3270 3271 async function sum(numbers: number[]): Promise<number> { 3272 let sum = 0 3273 for (let i = 0; i < numbers.length; ++i) { 3274 sum += await numbers[i] 3275 } 3276 return sum 3277 } 3278 3279 ... 3280 const result = sum(5, 10) 3281 ... 3282 3283.. _R096: 3284 3285|CB_R| #96: Type guarding is supported with ``instanceof`` and ``as`` 3286--------------------------------------------------------------------- 3287 3288|CB_RULE| 3289~~~~~~~~~ 3290 3291|LANG| does not support the ``is`` operator, which must be replaced by the 3292``instanceof`` operator. Note that the fields of an object must be cast to the 3293appropriate type with the ``as`` operator before use. 3294 3295|CB_BAD| 3296~~~~~~~~ 3297 3298.. code-block:: typescript 3299 3300 class Foo { 3301 foo: number = 0 3302 common: string = "" 3303 } 3304 3305 class Bar { 3306 bar: number = 0 3307 common: string = "" 3308 } 3309 3310 function isFoo(arg: any): arg is Foo { 3311 return arg.foo !== undefined 3312 } 3313 3314 function doStuff(arg: Foo | Bar) { 3315 if (isFoo(arg)) { 3316 console.log(arg.foo) // OK 3317 console.log(arg.bar) // Error! 3318 } 3319 else { 3320 console.log(arg.foo) // Error! 3321 console.log(arg.bar) // OK 3322 } 3323 } 3324 3325 doStuff({ foo: 123, common: '123' }) 3326 doStuff({ bar: 123, common: '123' }) 3327 3328|CB_OK| 3329~~~~~~~ 3330 3331.. code-block:: typescript 3332 3333 class Foo { 3334 foo: number = 0 3335 common: string = "" 3336 } 3337 3338 class Bar { 3339 bar: number = 0 3340 common: string = "" 3341 } 3342 3343 function isFoo(arg: Object): boolean { 3344 return arg instanceof Foo 3345 } 3346 3347 function doStuff(arg: Object): void { 3348 if (isFoo(arg)) { 3349 let fooArg = arg as Foo 3350 console.log(fooArg.foo) // OK 3351 console.log(arg.bar) // Error! 3352 } 3353 else { 3354 let barArg = arg as Bar 3355 console.log(arg.foo) // Error! 3356 console.log(barArg.bar) // OK 3357 } 3358 } 3359 3360 function main(): void { 3361 doStuff(new Foo()) 3362 doStuff(new Bar()) 3363 } 3364 3365.. _R098: 3366 3367|CB_R| #98: Spreading an array into function arguments is not supported 3368----------------------------------------------------------------------- 3369 3370|CB_RULE| 3371~~~~~~~~~ 3372 3373|LANG| does not support the spread operator. 3374"Unpack" data from an array to a callee manually. 3375 3376|CB_BAD| 3377~~~~~~~~ 3378 3379.. code-block:: typescript 3380 3381 function foo(x, y, z) {} 3382 3383 let args = [0, 1, 2] 3384 foo(...args) 3385 3386|CB_OK| 3387~~~~~~~ 3388 3389.. code-block:: typescript 3390 3391 function foo(x: number, y: number, z: number): void {} 3392 3393 function main(): void { 3394 let args: number[] = [0, 1, 2] 3395 foo(args[0], args[1], args[2]) 3396 } 3397 3398.. _R099: 3399 3400|CB_R| #99: Spread operator is not supported 3401-------------------------------------------- 3402 3403|CB_RULE| 3404~~~~~~~~~ 3405 3406|LANG| does not support the spread operator. 3407"Unpack" data from arrays indices manually where necessary. 3408 3409|CB_BAD| 3410~~~~~~~~ 3411 3412.. code-block:: typescript 3413 3414 let list = [1, 2] 3415 list = [...list, 3, 4] 3416 3417|CB_OK| 3418~~~~~~~ 3419 3420.. code-block:: typescript 3421 3422 let list: number[] = [1, 2] 3423 list = [list[0], list[1], 3, 4] 3424 3425.. _R100: 3426 3427|CB_R| #100: Spreading an object is not supported 3428--------------------------------------------------- 3429 3430|CB_RULE| 3431~~~~~~~~~ 3432 3433|LANG| does not support the spread operator. 3434"Unpack" data from an object to a callee manually, field by field. 3435 3436|CB_BAD| 3437~~~~~~~~ 3438 3439.. code-block:: typescript 3440 3441 const point2d = {x: 1, y: 2} 3442 const point3d = {...point2d, z: 3} 3443 3444|CB_OK| 3445~~~~~~~ 3446 3447.. code-block:: typescript 3448 3449 class Point2D { 3450 x: number 3451 y: number 3452 3453 constructor(x: number, y: number) { 3454 this.x = x 3455 this.y = y 3456 } 3457 } 3458 3459 class Point3D { 3460 x: number 3461 y: number 3462 z: number 3463 3464 constructor(x: number, y: number, z: number) { 3465 this.x = x 3466 this.y = y 3467 this.z = z 3468 } 3469 } 3470 3471 function main(): void { 3472 const point2d = new Point2D(1, 2) 3473 const point3d = new Point3D(point2d.x, point2d.y, 3) 3474 } 3475 3476|CB_R| #101: Interfaces with optional properties and call signatures are not supported 3477-------------------------------------------------------------------------------------- 3478 3479|CB_RULE| 3480~~~~~~~~~ 3481 3482|LANG| does not support interfaces with optional properties and interfaces 3483with call signatures. 3484 3485|CB_BAD| 3486~~~~~~~~ 3487 3488.. code:: typescript 3489 3490 // Interface with optional properties 3491 interface Person { 3492 firstName: string 3493 lastName: string 3494 age?: number 3495 } 3496 3497 // Interface with call signature 3498 interface Greet { 3499 (name: string): string 3500 } 3501 3502|CB_OK| 3503~~~~~~~ 3504 3505.. code:: typescript 3506 3507 // Use nullable type instead of optional property 3508 interface Person { 3509 firstName: string 3510 lastName: string 3511 age: number | null 3512 } 3513 3514 // Use a method signature instead of call signature 3515 interface Greet { 3516 action (name: string): string 3517 } 3518 3519 3520 3521|CB_R| #102: Interface declarations (extends same property) 3522----------------------------------------------------------- 3523 3524|CB_RULE| 3525~~~~~~~~~ 3526 3527|LANG| does not allow an interface to contain two methods with signatures that 3528are not distinguishable, e.g., two methods that have the same parameter lists 3529but different return types. 3530 3531|CB_BAD| 3532~~~~~~~~ 3533 3534.. code:: typescript 3535 3536 interface Mover { 3537 getStatus(): { speed: number } 3538 } 3539 interface Shaker { 3540 getStatus(): { frequency: number } 3541 } 3542 3543 interface MoverShaker extends Mover, Shaker { 3544 getStatus(): { speed: number; frequency: number } 3545 } 3546 3547 class C implements MoverShaker { 3548 private speed: number = 0 3549 private frequency: number = 0 3550 3551 getStatus() { 3552 return { speed: this.speed, frequency: this.frequency } 3553 } 3554 } 3555 3556In |TS|, an interface that extends ``Mover`` and ``Shaker`` must declare a 3557new ``getStatus`` with a combined result type. It is not allowed in |LANG|. 3558 3559.. _R103: 3560 3561|CB_R| #103: Declaration merging is not supported 3562------------------------------------------------- 3563 3564|CB_RULE| 3565~~~~~~~~~ 3566 3567|LANG| does not support merging declratations. All definitions of classes, 3568interfaces and so on must be kept compact in the code base. 3569 3570|CB_BAD| 3571~~~~~~~~ 3572 3573.. code-block:: typescript 3574 3575 interface Document { 3576 createElement(tagName: any): Element 3577 } 3578 3579 interface Document { 3580 createElement(tagName: string): HTMLElement 3581 } 3582 3583 interface Document { 3584 createElement(tagName: number): HTMLDivElement 3585 createElement(tagName: boolean): HTMLSpanElement 3586 createElement(tagName: string, value: number): HTMLCanvasElement 3587 } 3588 3589|CB_OK| 3590~~~~~~~ 3591 3592.. code-block:: typescript 3593 3594 interface Document { 3595 createElement(tagName: number): HTMLDivElement 3596 createElement(tagName: boolean): HTMLSpanElement 3597 createElement(tagName: string, value: number): HTMLCanvasElement 3598 createElement(tagName: string): HTMLElement 3599 createElement(tagName: Object): Element 3600 } 3601 3602.. _R104: 3603 3604|CB_R| #104: Interfaces cannot extend classes 3605--------------------------------------------- 3606 3607|CB_RULE| 3608~~~~~~~~~ 3609 3610|LANG| does not support interfaces that extend classes. Interfaces can extend 3611only interfaces. 3612 3613|CB_BAD| 3614~~~~~~~~ 3615 3616.. code-block:: typescript 3617 3618 class Control { 3619 state: number = 0 3620 } 3621 3622 interface SelectableControl extends Control { 3623 select(): void 3624 } 3625 3626|CB_OK| 3627~~~~~~~ 3628 3629.. code-block:: typescript 3630 3631 interface Control { 3632 state: number = 0 3633 } 3634 3635 interface SelectableControl extends Control { 3636 select(): void 3637 } 3638 3639.. _R105: 3640 3641|CB_R| #105: Property-based runtime type checks are not supported 3642----------------------------------------------------------------- 3643 3644|CB_RULE| 3645~~~~~~~~~ 3646 3647|LANG| requires that object layout is determined in compile-time and cannot 3648be changed at runtime. There for no runtime property-based checks are supported. 3649If you need to do a type cast, use ``as`` operator and use desired properties 3650and methods. If some property doesn't exist then an attempt to reference it 3651will result in a compile-time error. 3652 3653|CB_BAD| 3654~~~~~~~~ 3655 3656.. code-block:: typescript 3657 3658 class A { 3659 foo() {} 3660 bar() {} 3661 } 3662 3663 function getSomeObject() { 3664 return new A() 3665 } 3666 3667 let obj: any = getSomeObject() 3668 if (obj && obj.foo && obj.bar) { 3669 console.log("Yes") // prints "Yes" in this example 3670 } else { 3671 console.log("No") 3672 } 3673 3674|CB_OK| 3675~~~~~~~ 3676 3677.. code-block:: typescript 3678 3679 class A { 3680 foo(): void {} 3681 bar(): void {} 3682 } 3683 3684 function getSomeObject(): A { 3685 return new A() 3686 } 3687 3688 function main(): void { 3689 let tmp: Object = getSomeObject() 3690 let obj: A = tmp as A 3691 obj.foo() // OK 3692 obj.bar() // OK 3693 obj.some_foo() // Compile-time error: Method some_foo does not exist on this type 3694 } 3695 3696|CB_SEE| 3697~~~~~~~~ 3698 3699* :ref:`R001` 3700* :ref:`R002` 3701* :ref:`R052` 3702* :ref:`R059` 3703* :ref:`R060` 3704* :ref:`R066` 3705* :ref:`R109` 3706 3707.. _R106: 3708 3709|CB_R| #106: Constructor function type is not supported 3710------------------------------------------------------- 3711 3712|CB_RULE| 3713~~~~~~~~~ 3714 3715|LANG| does not support the usage of the constructor function type. 3716Use lambdas instead, as they can be generalized to several types of objects. 3717 3718|CB_BAD| 3719~~~~~~~~ 3720 3721.. code-block:: typescript 3722 3723 class Person { 3724 constructor( 3725 name: string, 3726 age: number 3727 ) {} 3728 } 3729 3730 type PersonConstructor = new (name: string, age: number) => Person 3731 3732 function createPerson(Ctor: PersonConstructor, name: string, age: number): Person { 3733 return new Ctor(name, age) 3734 } 3735 3736 const person = createPerson(Person, 'John', 30) 3737 3738|CB_OK| 3739~~~~~~~ 3740 3741.. code-block:: typescript 3742 3743 class Person { 3744 constructor( 3745 name: string, 3746 age: number 3747 ) {} 3748 } 3749 3750 let PersonConstructor: (name: string, age: number): Person = (name: string, age: number): Person => { 3751 return new Person(name, age) 3752 } 3753 3754 function createPerson(Ctor: (name: string, age: number): Person, name: string, age: number): Person { 3755 return PersonConstructor(name, age) 3756 } 3757 3758 function main(): void { 3759 const person = createPerson(PersonConstructor, "John", 30) 3760 } 3761 3762.. _R107: 3763 3764|CB_R| #107: Constructor declarations 3765------------------------------------- 3766 3767|CB_RULE| 3768~~~~~~~~~ 3769 3770|LANG| does not support optional parameters in constructors. 3771Constructors are not inherited from a superclass to a subclass. Use overloading 3772constructors instead of constructors with optional parameters: 3773 3774|CB_BAD| 3775~~~~~~~~ 3776 3777.. code:: typescript 3778 3779 class Foo { 3780 constructor(bar: string = 'default', baz?: number) {} 3781 } 3782 3783|CB_OK| 3784~~~~~~~ 3785 3786.. code:: typescript 3787 3788 class Foo { 3789 constructor(bar: string) {} 3790 constructor(bar: string, baz: number) {} 3791 } 3792 3793|CB_RULE| 3794~~~~~~~~~ 3795 3796In |LANG|, constructors are not inherited from a superclass. 3797 3798|CB_BAD| 3799~~~~~~~~ 3800 3801The constructor defined in a superclass can be used in a subclass. 3802 3803.. code:: typescript 3804 3805 class C1 { 3806 constructor(bar: string, baz: number) {} 3807 } 3808 class C2 extends Foo {} 3809 3810 let c = C2("a", "b") 3811 3812|CB_OK| 3813~~~~~~~ 3814 3815A subclass must define its own constructor. 3816 3817.. code:: typescript 3818 3819 class C1 { 3820 constructor(bar: string, baz: number) {} 3821 } 3822 class C2 extends Foo { 3823 constructor(bar: string, baz: number) { 3824 super(bar, string) 3825 } 3826 } 3827 3828 let c = C2("a", "b") 3829 3830|CB_SEE| 3831~~~~~~~~ 3832 3833* :ref:`R015` 3834 3835.. _R108: 3836 3837|CB_R| #108: Overloaded constructors with shared body are not supported 3838----------------------------------------------------------------------- 3839 3840|CB_RULE| 3841~~~~~~~~~ 3842 3843|LANG| does not support sharing a body between function overloads. 3844The shared body feature for ``constructor`` is not supported, either. 3845Overload constructor with a separate body for each signature. 3846 3847|CB_BAD| 3848~~~~~~~~ 3849 3850.. code-block:: typescript 3851 3852 class Person { 3853 name: string 3854 age: number 3855 3856 constructor(name: string, age?: number) { 3857 this.name = name 3858 if (age) { 3859 this.age = age 3860 } else { 3861 this.age = 0 3862 } 3863 } 3864 } 3865 3866|CB_OK| 3867~~~~~~~ 3868 3869.. code-block:: typescript 3870 3871 class Person { 3872 name: string 3873 age: number 3874 3875 constructor(name: string, age: number) { 3876 this.name = name 3877 this.age = age 3878 } 3879 3880 constructor(name: string) { 3881 this.name = name 3882 this.age = 0 3883 } 3884 } 3885 3886.. _R109: 3887 3888|CB_R| #109: Dynamic property declaration is not supported 3889---------------------------------------------------------- 3890 3891|CB_RULE| 3892~~~~~~~~~ 3893 3894|LANG| does not support dynamic property declaration. All object properties must 3895be declared immediately in the class. While it can be replaced with an array 3896of objects, it is still better to adhere to the static language paradigm and 3897declare fields, their names and types explicitly. 3898 3899|CB_BAD| 3900~~~~~~~~ 3901 3902.. code-block:: typescript 3903 3904 class Person { 3905 name: string = "" 3906 age: number = 0 3907 [key: string]: string | number 3908 } 3909 3910 const person: Person = { 3911 name: "John", 3912 age: 30, 3913 email: "john@example.com", 3914 phone: 1234567890, 3915 } 3916 3917|CB_OK| 3918~~~~~~~ 3919 3920.. code-block:: typescript 3921 3922 class Person { 3923 name: string 3924 age: number 3925 email: string 3926 phone: number 3927 3928 constructor(name: string, age: number, email: string, phone: number) { 3929 this.name = name 3930 this.age = age 3931 this.email = email 3932 this.phone = phone 3933 } 3934 } 3935 3936 function main(): void { 3937 const person: Person = new Person("John", 30, "john@example.com", 1234567890) 3938 } 3939 3940|CB_SEE| 3941~~~~~~~~ 3942 3943* :ref:`R001` 3944* :ref:`R002` 3945* :ref:`R052` 3946* :ref:`R059` 3947* :ref:`R060` 3948* :ref:`R066` 3949* :ref:`R105` 3950 3951.. _R111: 3952 3953|CB_R| #111: Explicit values for enumeration constants are not supported 3954------------------------------------------------------------------------ 3955 3956|CB_RULE| 3957~~~~~~~~~ 3958 3959Currently, |LANG| does not support assigning explicit values for ``enums``. 3960 3961|CB_BAD| 3962~~~~~~~~ 3963 3964.. code-block:: typescript 3965 3966 enum E { 3967 A, 3968 B, 3969 C = 10, 3970 D 3971 } 3972 3973|CB_OK| 3974~~~~~~~ 3975 3976.. code-block:: typescript 3977 3978 enum E { 3979 A, 3980 B, 3981 C = 10, // Compile-time error: assigning out of order values for enums is not supported 3982 D 3983 } 3984 3985 enum E_fixed { 3986 A, 3987 B, 3988 C, // OK 3989 D 3990 } 3991 3992.. _R112: 3993 3994.. _R113: 3995 3996|CB_R| #113: ``enum`` declaration merging is not supported 3997---------------------------------------------------------- 3998 3999|CB_RULE| 4000~~~~~~~~~ 4001 4002|LANG| does not support merging declratations for ``enum``. 4003The declaration of each ``enum`` must be kept compact in the code base. 4004 4005|CB_BAD| 4006~~~~~~~~ 4007 4008.. code:: typescript 4009 4010 enum Color { 4011 RED, 4012 GREEN 4013 } 4014 enum Color { 4015 YELLOW 4016 } 4017 enum Color { 4018 BLACK, 4019 BLUE 4020 } 4021 4022|CB_OK| 4023~~~~~~~ 4024 4025.. code:: typescript 4026 4027 enum Color { 4028 RED, 4029 GREEN, 4030 YELLOW, 4031 BLACK, 4032 BLUE 4033 } 4034 4035.. _R114: 4036 4037|CB_R| #114: Namespaces cannot be used as objects 4038------------------------------------------------- 4039 4040|CB_RULE| 4041~~~~~~~~~ 4042 4043|LANG| does not support the usage of namespaces as objects. 4044Classes or modules can be interpreted as analogues of namespaces. 4045 4046|CB_BAD| 4047~~~~~~~~ 4048 4049.. code-block:: typescript 4050 4051 namespace MyNamespace { 4052 export let x: number 4053 } 4054 4055 let m = MyNamespace 4056 m.x = 2 4057 4058|CB_OK| 4059~~~~~~~ 4060 4061.. code-block:: typescript 4062 4063 namespace MyNamespace { 4064 export let x: number 4065 } 4066 4067 MyNamespace.x = 2 4068 4069.. _R115: 4070 4071|CB_R| #115: Scripts and modules 4072-------------------------------- 4073 4074|CB_RULE| 4075~~~~~~~~~ 4076 4077In general, scripts and modules in |LANG| are very close to |TS|. 4078Differences are described in separate recipes. 4079 4080|CB_SEE| 4081~~~~~~~~ 4082 4083* :ref:`R117` 4084* :ref:`R118` 4085* :ref:`R119` 4086* :ref:`R120` 4087* :ref:`R121` 4088* :ref:`R122` 4089* :ref:`R124` 4090* :ref:`R125` 4091* :ref:`R126` 4092 4093.. _R116: 4094 4095|CB_R| #116: Non-declaration statements in namespaces are not supported 4096----------------------------------------------------------------------- 4097 4098|CB_RULE| 4099~~~~~~~~~ 4100 4101|LANG| does not support statements in namespaces. Use a function to exectute statements. 4102 4103|CB_BAD| 4104~~~~~~~~~ 4105 4106.. code:: typescript 4107 4108 namespace A { 4109 export let x: number 4110 x = 1 4111 } 4112 4113|CB_OK| 4114~~~~~~~~~ 4115 4116Initialization function should be called to execute statements. 4117 4118.. code:: typescript 4119 4120 namespace A { 4121 export let x: number 4122 4123 export function init() { 4124 x = 1 4125 } 4126 } 4127 A.init() 4128 4129 4130.. _R117: 4131 4132|CB_R| #117: Statement as top-level element 4133------------------------------------------- 4134 4135|CB_RULE| 4136~~~~~~~~~ 4137 4138|LANG| does not support statements as top-level elements. Statements must be 4139placed in a block ``{}``. 4140 4141|CB_BAD| 4142~~~~~~~~~ 4143 4144.. code:: typescript 4145 4146 let a = 1 4147 let b = 2 4148 if (b == a) { 4149 console.log("a EQ b") 4150 } else { 4151 console.log("a NEQ b") 4152 } 4153 4154|CB_OK| 4155~~~~~~~~~ 4156 4157.. code:: typescript 4158 4159 // A block can be a top-level element, 4160 // put statements inside one or several blocks: 4161 { 4162 let a = 1 4163 let b = 2 4164 } 4165 4166 { 4167 if (b == a) { 4168 console.log("a EQ b") 4169 } else { 4170 console.log("a NEQ b") 4171 } 4172 } 4173 4174 4175.. _R118: 4176 4177|CB_R| #118: Special import type declarations are not supported 4178--------------------------------------------------------------- 4179 4180|CB_RULE| 4181~~~~~~~~~ 4182 4183|LANG| does not have a special notation for importing types. 4184Use ordinary import instead. 4185 4186|CB_BAD| 4187~~~~~~~~ 4188 4189.. code:: typescript 4190 4191 // Re-using the same import 4192 import { APIResponseType } from "./api" 4193 4194 // Explicitly use import type 4195 import type { APIResponseType } from "./api" 4196 4197|CB_OK| 4198~~~~~~~ 4199 4200.. code:: typescript 4201 4202 import { APIResponseType } from "./api" 4203 4204|CB_SEE| 4205~~~~~~~~ 4206 4207* :ref:`R119` 4208* :ref:`R120` 4209* :ref:`R121` 4210 4211.. _R119: 4212 4213|CB_R| #119: Importing a module for side-effects only is not supported 4214---------------------------------------------------------------------- 4215 4216|CB_RULE| 4217~~~~~~~~~ 4218 4219|LANG| does not support global variables like ``window`` to avoid 4220side-effects during module importing. All variables marked as export can be 4221accessed through the ``*`` syntax. 4222 4223|CB_BAD| 4224~~~~~~~~ 4225 4226.. code:: typescript 4227 4228 // === module at "path/to/module.ts" 4229 export const EXAMPLE_VALUE = 42 4230 4231 // Set a global variable 4232 window.MY_GLOBAL_VAR = "Hello, world!" 4233 4234 // ==== using this module: 4235 import "path/to/module" 4236 4237|CB_OK| 4238~~~~~~~ 4239 4240.. code:: typescript 4241 4242 import * from "path/to/module" 4243 4244.. _R120: 4245 4246|CB_R| #120: ``import default as ...`` is not supported 4247------------------------------------------------------- 4248 4249|CB_RULE| 4250~~~~~~~~~ 4251 4252|LANG| does not support ``import default as ...`` syntax. 4253Use explicit ``import ... from ...`` instead. 4254 4255|CB_BAD| 4256~~~~~~~~ 4257 4258.. code-block:: typescript 4259 4260 import { default as d } from "mod" 4261 4262|CB_OK| 4263~~~~~~~ 4264 4265.. code-block:: typescript 4266 4267 import d from "mod" 4268 4269|CB_SEE| 4270~~~~~~~~ 4271 4272* :ref:`R122` 4273 4274.. _R121: 4275 4276|CB_R| #121: ``require`` is not supported 4277----------------------------------------- 4278 4279|CB_RULE| 4280~~~~~~~~~ 4281 4282|LANG| does not support importing via ``require``. Use ``import`` instead. 4283 4284|CB_BAD| 4285~~~~~~~~ 4286 4287.. code-block:: typescript 4288 4289 import m = require("mod") 4290 4291|CB_OK| 4292~~~~~~~ 4293 4294.. code-block:: typescript 4295 4296 import * as m from "mod" 4297 4298.. _R122: 4299 4300|CB_R| #122: ``export default`` is not supported 4301------------------------------------------------ 4302 4303|CB_RULE| 4304~~~~~~~~~ 4305 4306|LANG| does not support ``export default``. 4307 4308|CB_BAD| 4309~~~~~~~~ 4310 4311.. code-block:: typescript 4312 4313 // file1.ts 4314 export default class MyClass { 4315 // ... 4316 } 4317 4318 // file2.ts 4319 // Can write just `MyClass` instead of `{ MyClass }` in case of default export 4320 import MyClass from './file1' 4321 4322|CB_OK| 4323~~~~~~~ 4324 4325.. code-block:: typescript 4326 4327 // module1 4328 export class MyClass { 4329 // ... 4330 } 4331 4332 // module2 4333 // Use explicit name in import 4334 import { MyClass } from "./module1" 4335 4336|CB_SEE| 4337~~~~~~~~ 4338 4339* :ref:`R120` 4340 4341.. _R124: 4342 4343|CB_R| #124: Export list declaration is not supported 4344----------------------------------------------------- 4345 4346|CB_RULE| 4347~~~~~~~~~ 4348 4349|LANG| does not support syntax of export list declarations. All exported 4350entities must be explicitly annotated with the ``export`` keyword. 4351 4352|CB_BAD| 4353~~~~~~~~ 4354 4355.. code-block:: typescript 4356 4357 export { x } 4358 export { x } from "mod" 4359 export { x, y as b, z as c } 4360 4361|CB_OK| 4362~~~~~~~ 4363 4364.. code-block:: typescript 4365 4366 let x = 1 4367 class MyClass {} 4368 export let y = x, z: number = 2 4369 export RenamedClass = MyClass 4370 4371|CB_SEE| 4372~~~~~~~~ 4373 4374* :ref:`R125` 4375* :ref:`R126` 4376 4377.. _R125: 4378 4379|CB_R| #125: Re-exporting is not supported 4380------------------------------------------ 4381 4382|CB_RULE| 4383~~~~~~~~~ 4384 4385|LANG| does not support re-exporting. All desired entities must be 4386imported explicitly from the modules that export them. 4387 4388|CB_BAD| 4389~~~~~~~~ 4390 4391.. code-block:: typescript 4392 4393 // module1 4394 export class MyClass { 4395 // ... 4396 } 4397 4398 // module2 4399 export { MyClass } from "module1" 4400 4401 // consumer module 4402 import { MyClass } from "module2" 4403 4404 const myInstance = new MyClass() 4405 4406|CB_OK| 4407~~~~~~~ 4408 4409.. code-block:: typescript 4410 4411 // module1 4412 export class MyClass { 4413 // ... 4414 } 4415 4416 // module2 4417 // some stuff 4418 4419 // consumer module 4420 import MyClass from "module1" 4421 import * from "module2" 4422 4423 const myInstance = new MyClass() 4424 4425|CB_SEE| 4426~~~~~~~~ 4427 4428* :ref:`R124` 4429* :ref:`R126` 4430 4431.. _R126: 4432 4433|CB_R| #126: ``export = ...`` assignment is not supported 4434--------------------------------------------------------- 4435 4436|CB_RULE| 4437~~~~~~~~~ 4438 4439|LANG| does not support ``export = ...`` syntax. 4440Use regular ``export`` / ``import`` instead. 4441 4442|CB_BAD| 4443~~~~~~~~ 4444 4445.. code-block:: typescript 4446 4447 // module1 4448 export = Point 4449 4450 class Point { 4451 constructor(x: number, y: number) {} 4452 static origin = new Point(0, 0) 4453 } 4454 4455 // module2 4456 import Pt = require("module1") 4457 4458 let p = Pt.origin 4459 4460|CB_OK| 4461~~~~~~~ 4462 4463.. code-block:: typescript 4464 4465 // module1 4466 export class Point { 4467 constructor(x: number, y: number) {} 4468 static origin = new Point(0, 0) 4469 } 4470 4471 // module2 4472 import * as Pt from "module1" 4473 4474 let p = Pt.origin 4475 4476|CB_SEE| 4477~~~~~~~~ 4478 4479* :ref:`R124` 4480* :ref:`R125` 4481 4482 4483.. _R127: 4484 4485|CB_R| #127: Special export type declarations are not supported 4486--------------------------------------------------------------- 4487 4488|CB_RULE| 4489~~~~~~~~~ 4490 4491|LANG| does not have a special notation for exporting types. 4492Use ordinary export instead. 4493 4494|CB_BAD| 4495~~~~~~~~ 4496 4497.. code:: typescript 4498 4499 class C {} 4500 export type { C } 4501 4502|CB_OK| 4503~~~~~~~ 4504 4505.. code:: typescript 4506 4507 export class C {} 4508 4509