1.. 2 Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 13.. _Semantic Rules: 14 15Semantic Rules 16############## 17 18.. meta: 19 frontend_status: Done 20 21This Chapter contains semantic rules to be used throughout the Specification 22document. The description of the rules is more or less informal. Some details 23are omitted to simplify the understanding. 24 25| 26 27.. _Subtyping: 28 29Subtyping 30********* 31 32.. meta: 33 frontend_status: Done 34 35The *subtype* relationship between the two types ``S`` and ``T``, where ``S`` 36is a subtype of ``T`` (recorded as ``S<:T``), means that any object of type 37``S`` can be safely used in any context to replace an object of type ``T``. 38The opposite is called *supertype* relationship (see :ref:`Supertyping`). 39 40By the definition of ``S<:T``, type ``T`` belongs to the set of *supertypes* 41of type ``S``. The set of *supertypes* includes all *direct supertypes* (see 42below), and all their respective *supertypes*. More formally speaking, the set 43is obtained by reflexive and transitive closure over the direct supertype 44relation. 45 46 47.. index:: 48 subtyping 49 subtype 50 closure 51 reflexive closure 52 transitive closure 53 object 54 type 55 direct supertype 56 supertype 57 58Terms *subclass*, *subinterface*, *superclass*, and *superinterface* are used 59when considering class or interface types. 60 61*Direct supertypes* of a non-generic class, or of the interface type ``C`` 62are **all** of the following: 63 64- Direct superclass of ``C`` (as mentioned in its extension clause, see 65 :ref:`Class Extension Clause`) or type ``Object`` if ``C`` has no extension 66 clause specified. 67 68- Direct superinterfaces of ``C`` (as mentioned in the implementation 69 clause of ``C``, see :ref:`Class Implementation Clause`). 70 71- Class ``Object`` if ``C`` is an interface type with no direct superinterfaces 72 (see :ref:`Superinterfaces and Subinterfaces`). 73 74 75.. index:: 76 subclass 77 subinterface 78 superclass 79 direct supertype 80 direct superclass 81 reflexive closure 82 transitive closure 83 non-generic class 84 extension clause 85 implementation clause 86 superinterface 87 Object 88 direct superinterface 89 class extension 90 subinterface 91 92*Direct supertypes* of the generic type ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`> 93(for a generic class or interface type declaration ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`> 94with *n*>0) are **all** of the following: 95 96- Direct superclass of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>. 97 98- Direct superinterfaces of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>. 99 100- Type ``Object`` if ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`> is a generic 101 interface type with no direct superinterfaces. 102 103 104The direct supertype of a type parameter is the type specified as the 105constraint of that type parameter. 106 107.. index:: 108 direct supertype 109 generic type 110 generic class 111 interface type declaration 112 direct superinterface 113 type parameter 114 superclass 115 superinterface 116 bound 117 Object 118 119| 120 121.. _Supertyping: 122 123Supertyping 124*********** 125 126.. meta: 127 frontend_status: Done 128 129The *supertype* relationship between the two types ``T`` and ``S``, where ``T`` 130is a supertype of ``T`` (recorded as ``T>:S``) is opposite to subtyping (see 131:ref:`Subtyping`). *Supertyping* means that any object of type ``S`` can be 132safely used in any context to replace an object of type ``T``. 133 134.. index:: 135 supertype 136 supertyping 137 context 138 type 139 object 140 141| 142 143.. _Variance: 144 145Variance 146******** 147 148.. meta: 149 frontend_status: Done 150 151Variance is how subtyping between class types relates to subtyping between 152class member signatures (types of parameters, return type). Variance can be 153of three kinds: 154 155- Invariance, 156- Covariance, and 157- Contravariance. 158 159.. index:: 160 variance 161 subtyping 162 type 163 class member signature 164 parameter 165 return type 166 invariance 167 covariance 168 contravariance 169 170| 171 172.. _Invariance: 173 174Invariance 175========== 176 177.. meta: 178 frontend_status: Done 179 180*Invariance* refers to the ability to use the originally-specified type as a 181derived one. 182 183.. index:: 184 invariance 185 type 186 187| 188 189.. _Covariance: 190 191Covariance 192========== 193 194.. meta: 195 frontend_status: Done 196 197*Covariance* is the ability to use a type that is more specific than originally 198specified. 199 200.. index:: 201 covariance 202 type 203 204| 205 206.. _Contravariance: 207 208Contravariance 209============== 210 211.. meta: 212 frontend_status: Done 213 214*Contravariance* is the ability to use a type that is more general than 215originally specified. 216 217.. index:: 218 contravariance 219 type 220 221Examples 222======== 223 224The examples below illustrate valid and invalid usages of variance. 225If class ``Base`` is defined as follows: 226 227.. code-block:: typescript 228 :linenos: 229 230 class Base { 231 method_one(p: Base): Base {} 232 method_two(p: Derived): Base {} 233 method_three(p: Derived): Derived {} 234 } 235 236---then the code below is valid: 237 238.. code-block:: typescript 239 :linenos: 240 241 class Derived extends Base { 242 // invariance: parameter type and return type are unchanged 243 override method_one(p: Base): Base {} 244 245 // covariance for the return type: Derived is a subtype of Base 246 override method_two(p: Derived): Derived {} 247 248 // contravariance for parameter types: Base is a super type for Derived 249 override method_three(p: Base): Derived {} 250 } 251 252.. index:: 253 variance 254 255On the contrary, the following code causes compile-time errors: 256 257.. code-block-meta: 258 expect-cte 259 260.. code-block:: typescript 261 :linenos: 262 263 class Derived extends Base { 264 265 // covariance for parameter types is prohibited 266 override method_one(p: Derived): Base {} 267 268 // contravariance for the return type is prohibited 269 override method_tree(p: Derived): Base {} 270 } 271 272 273| 274 275.. _Type Compatibility: 276 277Type Compatibility 278****************** 279 280.. meta: 281 frontend_status: Done 282 283Type ``T``:sub:`1` is compatible with type ``T``:sub:`2` if: 284 285- ``T``:sub:`1` is the same as ``T``:sub:`2`, or 286 287- There is an *implicit conversion* (see :ref:`Implicit Conversions`) 288 that allows converting type ``T``:sub:`1` to type ``T``:sub:`2`. 289 290*Type compatibility* relationship is asymmetric, i.e., that ``T``:sub:`1` 291is compatible with type ``T``:sub:`2` does not imply that ``T``:sub:`2` is 292compatible with type ``T``:sub:`1`. 293 294 295.. index:: 296 type compatibility 297 conversion 298 implicit conversion 299 asymmetric relationship 300 301| 302 303.. _Compatibility of Call Arguments: 304 305Compatibility of Call Arguments 306******************************* 307 308.. meta: 309 frontend_status: Done 310 311The definition of the term *compatible* is found in :ref:`Type Compatibility`. 312 313The following semantic check must be performed for any function, method, or 314constructor call: 315 316- Type of any argument (except arguments of a rest parameter) must be 317 compatible with the type of the corresponding parameter; 318 319- Type of each argument corresponding to the rest parameter without the spread 320 operator (:ref:`Spread Expression`) must be compatible with the element type 321 of the rest type parameter; 322 323- If a single argument corresponding to the rest parameter has the spread 324 operator (:ref:`Spread Expression`), then the *expression* that follows the 325 operator must refer to an array of a type compatible with the type of the 326 rest parameter. 327 328.. index:: 329 call argument 330 function call 331 method call 332 constructor call 333 semantic check 334 argument 335 rest parameter 336 spread operator 337 compatible type 338 type 339 compatibility 340 341| 342 343.. _Type Inference: 344 345Type Inference 346************** 347 348.. meta: 349 frontend_status: Done 350 351In spite of the fact that |LANG| supports strong typing, it allows not to 352burden the programmer to specify type annotations everywhere. Smart compiler 353can infer the type of some entities from the surrounding context. This 354technique called *type inference* allows keeping program code readability, 355typing less, and focusing on the business logic while keeping type safety. 356Type inference can be applied by the compiler in several contexts as follows: 357 358- Variable and constant declarations (see :ref:`Type Inference from Initializer`); 359- Implicit generic instantiations (see :ref:`Implicit Generic Instantiations`); 360- Function or method return type (see :ref:`Return Type Inference`); 361- Lambda expression parameter type (see :ref:`Lambda Signature`); 362- Array literal type inference (see :ref:`Array Type Inference from Context`, 363 and :ref:`Array Type Inference from Types of Elements`); 364- Smart types (see :ref:`Smart Types`). 365 366.. index:: 367 strong typing 368 annotation 369 type inference 370 entity 371 code readability 372 type safety 373 context 374 variable 375 constant 376 declaration 377 generic instantiation 378 function 379 method 380 return type 381 lambda expression 382 parameter type 383 array literal 384 smart type 385 386| 387 388.. _Smart Types: 389 390Smart Types 391=========== 392 393.. meta: 394 frontend_status: Partly 395 todo: implement a dataflow check for loops and try-catch blocks 396 397Every data entity 398 399- a variable (see :ref:`Variable and Constant Declarations`), 400- a class field (see :ref:`Field Declarations`), 401- a parameter of a function or method (see :ref:`Parameter List`) 402 403has its static type, which is specified explicitly or inferred at the 404point of declaration. This type defines the set of operations that can 405be applied to the entity (namely, what methods can be called, and what other 406entities can be accessed if the entity acts as a receiver of the operation): 407 408.. code-block:: typescript 409 :linenos: 410 411 let a = new Object 412 a.toString() // entity 'a' has method toString() 413 414.. index:: 415 entity 416 variable 417 class variable 418 local variable 419 function 420 method 421 static type 422 receiver 423 access 424 declaration 425 426There can be cases when the type of an entity (mostly local variables) is a 427class or interface type (see :ref:`Classes` and :ref:`Interfaces`), or union 428type (see :ref:`Union Types`). In a particular program context, the compiler 429can narrow (smart cast) a static type to a more precise type (smart type), and 430allow the operations specific to the narrowed type: 431 432.. code-block:: typescript 433 :linenos: 434 435 let a: number | string = 666 436 a++ /* Here we know for sure that type of 'a' is number and number-specific 437 operations are type-safe */ 438 439 class Base {} 440 class Derived extends Base { method () {} } 441 let b: base = new Derived 442 b.method () /* Here we know for sure that type of 'b' is Derived and Derived-specific 443 operations are type-safe */ 444 445Other examples are explicit calls to ``instanceof`` 446(see :ref:`InstanceOf Expression`) or checks against ``null`` 447(see :ref:`Reference Equality`) as part of ``if`` statements 448(see :ref:`if Statements`) or conditional expressions 449(see :ref:`Conditional Expressions`): 450 451.. code-block:: typescript 452 :linenos: 453 454 function foo (b: Base, d: Derived|null) { 455 if (b instanceof Derived) { 456 b.method() 457 } 458 if (d != null) { 459 d.method() 460 } 461 } 462 463.. index:: 464 type 465 entity 466 local variable 467 interface type 468 class type 469 union type 470 context 471 compiler 472 narrowing 473 smart cast 474 smart type 475 if statement 476 conditional expression 477 478In cases like this, the smart compiler can deduce the smart type of an entity 479without requiring unnecessary ``as`` conversions (see :ref:`Cast Expressions`). 480 481Overloading (see :ref:`Function and Method Overloading`) can cause tricky 482situations when a smart type leads to the call of a function or a method 483(see :ref:`Overload Resolution`) that suits the smart type rather than the 484static type of an argument: 485 486.. code-block:: typescript 487 :linenos: 488 489 function foo (p: Base) {} 490 function foo (p: Derived) {} 491 492 let b: Base = new Derived 493 foo (b) // potential ambiguity in case of smart type, foo(p:Base) is to be called 494 foo (b as Derived) // no ambiguity, foo(p:Derived) is to be called 495 496Particular cases supported by the compiler are determined by the compiler 497implementation. 498 499.. index:: 500 compiler 501 smart type 502 entity 503 as conversion 504 conversion 505 function 506 method 507 static type 508 implementation 509 510| 511 512.. _Overloading and Overriding: 513 514Overloading and Overriding 515************************** 516 517Two important concepts apply to different contexts and entities throughout 518this specification as follows: 519 520#. *Overloading* allows defining and using functions (in general sense, 521 including methods and constructors) with the same name but different 522 signatures. The actual function to be called is determined at compile 523 time. Thus, *overloading* is related to compile-time polymorphism. 524 525#. *Overriding* is closely connected with inheritance. It is used on methods 526 but not on functions. Overriding allows a subclass to offer a specific 527 implementation of a method already defined in its parent class. 528 The actual method to be called is determined at runtime based on the 529 object's type. Thus, overriding is related to runtime polymorphism. 530 531|LANG| uses two semantic rules related to these concepts: 532 533- *Overload-equivalence* rule: the *overloading* of two entities is 534 correct if their signatures are **not** *overload-equivalent* (see 535 :ref:`Overload-Equivalent Signatures`). 536 537- *Override-compatibility* rule: the *overriding* of two entities is 538 correct if their signatures are *override-compatible* (see 539 :ref:`Override-Compatible Signatures`). 540 541See :ref:`Overloading for Functions`, 542:ref:`Overloading and Overriding in Classes`, and 543:ref:`Overloading and Overriding in Interfaces` for details. 544 545.. index:: 546 overloading 547 overriding 548 context 549 entity 550 function 551 constructor 552 method 553 signature 554 compile-time polymorphism 555 runtime polymorphism 556 inheritance 557 parent class 558 object type 559 runtime 560 overload-equivalence 561 override-compatibility 562 563| 564 565.. _Overload-Equivalent Signatures: 566 567Overload-Equivalent Signatures 568============================== 569 570Signatures *S*:sub:`1` with *n* parameters, and *S*:sub:`2` with *m* 571parameters are *overload-equivalent* if: 572 573- ``n = m``; 574 575- Parameter type at some position in *S*:sub:`1` is a *type parameter* 576 (see :ref:`Type Parameters`), and a parameter type at the same position 577 in *S*:sub:`2` is any reference type or type parameter; 578 579- Parameter type at some position in *S*:sub:`1` is *generic type* 580 ``G`` <``T``:sub:`1`, ``...``, ``T``:sub:`n`>, and a parameter type at the 581 same position in *S*:sub:`2` is also ``G`` with any list of type arguments 582 (see :ref:`Type Arguments`); 583 584- All other parameter types in *S*:sub:`1` are equal to parameter types 585 in the same positions in *S*:sub:`2`. 586 587Parameter names and return types do not influence *overload equivalence*. 588Signatures in the following series are *overload-equivalent*: 589 590.. index:: 591 overload-equivalent signature 592 signature 593 parameter 594 type parameter 595 reference type 596 generic type 597 type argument 598 overriding 599 parameter name 600 return type 601 overload equivalence 602 603.. code-block-meta: 604 605.. code-block:: typescript 606 :linenos: 607 608 (x: number): void 609 (y: number): void 610 611 612.. code-block-meta: 613 614.. code-block:: typescript 615 :linenos: 616 617 (x: number): void 618 (y: number): number 619 620 621.. code-block-meta: 622 623.. code-block:: typescript 624 :linenos: 625 626 class G<T> 627 (y: Number): void 628 (x: T): void 629 630 631.. code-block-meta: 632 633.. code-block:: typescript 634 :linenos: 635 636 class G<T> 637 (y: G<Number>): void 638 (x: G<T>): void 639 640 641.. code-block-meta: 642 643.. code-block:: typescript 644 :linenos: 645 646 class G<T, S> 647 (y: T): void 648 (x: S): void 649 650Signatures in the following series are not *overload-equivalent*: 651 652.. code-block-meta: 653 654.. code-block:: typescript 655 :linenos: 656 657 (x: number): void 658 (y: string): void 659 660 661.. code-block-meta: 662 663.. code-block:: typescript 664 :linenos: 665 666 class A { /*body*/} 667 class B extends A { /*body*/} 668 (x: A): void 669 (y: B): void 670 671 672| 673 674.. _Override-Compatible Signatures: 675 676Override-Compatible Signatures 677============================== 678 679If there are two classes, ``Base`` and ``Derived``, and class ``Derived`` 680overrides the method ``foo()`` of ``Base``, then ``foo()`` in ``Base`` has 681signature ``S``:sub:`1` <``V``:sub:`1` ``, ... V``:sub:`k`> 682(``U``:sub:`1` ``, ..., U``:sub:`n`) ``:U``:sub:`n+1`, and ``foo()`` in 683``Derived`` has signature ``S``:sub:`2` <``W``:sub:`1` ``, ... W``:sub:`l`> 684(``T``:sub:`1` ``, ..., T``:sub:`m`) ``:T``:sub:`m+1` as illustrated by the 685example below: 686 687.. code-block:: typescript 688 :linenos: 689 690 class Base { 691 foo <V1, ... Vk> (p1: U1, ... pn: Un): Un+1 692 } 693 class Derived extends Base { 694 override foo <W1, ... Wl> (p1: T1, ... pm: Tm): Tm+1 695 } 696 697The signature ``S``:sub:`2` is override-compatible with ``S``:sub:`1` only 698if **all** of the following conditions are met: 699 7001. Number of parameters of both methods is the same, i.e., ``n = m``. 7012. Each type ``T``:sub:`i` is override-compatible with type ``U``:sub:`i` 702 for ``i`` in ``1..n+1``. Type override compatibility is defined below. 7033. Number of type parameters of either method is the same, i.e., ``k = l``. 7044. Constraints of ``W``:sub:`1`, ... ``W``:sub:`l` are to be contravariant 705 (see :ref:`Contravariance`) to the appropriate constraints of ``V``:sub:`1`, 706 ... ``V``:sub:`k`. 707 708.. index:: 709 override-compatible signature 710 override compatibility 711 class 712 signature 713 method 714 parameter 715 type 716 contravariant 717 constraint 718 type parameter 719 720There are two cases of type override-compatibility, as types are used as either 721parameter types, or return types. There are five kinds of types for each case: 722 723- Class/interface type; 724- Function type; 725- Primitive type; 726- Array type; 727- Tuple type; and 728- Type parameter. 729 730Every type is override-compatible with itself (see :ref:`Invariance`). 731 732Mixed override-compatibility between types of different kinds is always false, 733except the compatibility with class type ``Object`` as any type is a subtype of 734``Object``. 735 736The following rule applies in case of generics: 737 738 - Derived class must have type parameter constraints to be type-compatible 739 (see :ref:`Type Compatibility`) with the respective type parameter 740 constraint in the base type; 741 - Otherwise, a :index:`compile-time error` occurs. 742 743.. index:: 744 override compatibility 745 parameter type 746 class type 747 interface type 748 function type 749 primitive type 750 array type 751 tuple type 752 type parameter 753 subtype 754 object 755 756.. code-block:: typescript 757 :linenos: 758 759 class Base {} 760 class Derived extends Base {} 761 class A1 <CovariantTypeParameter extends Base> {} 762 class B1 <CovariantTypeParameter extends Derived> extends A1<CovariantTypeParameter> {} 763 // OK, derived class may have type compatible constraint of type parameters 764 765 class A2 <ContravariantTypeParameter extends Derived> {} 766 class B2 <ContravariantTypeParameter extends Base> extends A2<ContravariantTypeParameter> {} 767 // Compile-time error, derived class cannot have non-compatible constraints of type parameters 768 769 770Variances to be used for types that can be override-compatible in different 771positions are represented in the following table: 772 773+-+-----------------------+---------------------+-------------------+ 774| | **Positions ==>** | **Parameter Types** | **Return Types** | 775+-+-----------------------+---------------------+-------------------+ 776| | **Type Kinds** | | | 777+=+=======================+=====================+===================+ 778|1| Class/interface types | Contravariance >: | Covariance <: | 779+-+-----------------------+---------------------+-------------------+ 780|2| Function types | Covariance <: | Contravariance >: | 781+-+-----------------------+---------------------+-------------------+ 782|3| Primitive types | Invariance | Invariance | 783+-+-----------------------+---------------------+-------------------+ 784|4| Array types | Covariance <: | Covariance <: | 785+-+-----------------------+---------------------+-------------------+ 786|5| Tuple types | Covariance <: | Covariance <: | 787+-+-----------------------+---------------------+-------------------+ 788|6| Type parameter | Contravariance >: | Contravariance >: | 789| | constraint | | | 790+-+-----------------------+---------------------+-------------------+ 791 792 793.. index:: 794 variance 795 covariance 796 contravariance 797 invariance 798 semantics 799 800The semantics is illustrated by the example below: 801 802.. code-block:: typescript 803 :linenos: 804 805 class Base { 806 kinds_of_parameters <T extends Derived, U extends Base>( 807 p1: Derived, p2: (q: Base)=>Derived, p3: number, 808 p4: Number, p5: Base[], p6: [Base, Base], p7: T, p8: U 809 ) 810 kinds_of_return_type1(): Base 811 kinds_of_return_type2(): (q: Derived)=> Base 812 kinds_of_return_type3(): number 813 kinds_of_return_type4(): Number 814 kinds_of_return_type5(): Base[] 815 kinds_of_return_type6(): [Base, Base] 816 kinds_of_return_type7 <T extends Derived>(): T 817 } 818 class Derived extends Base { 819 // Overriding kinds for parameters 820 override kinds_of_parameters <T extends Base, U extends Object>( 821 p1: Base, // contravariant parameter type 822 p2: (q: Derived)=>Base, // Covariant parameter type, contravariant return type 823 p3: Number, // Compile-time error: parameter type is not override-compatible 824 p4: number, // Compile-time error: parameter type is not override-compatible 825 p5: Derived[], // Covariant array element type 826 p6: [Derived, Derived], // Covariant tuple type elements 827 p7: T, // Contravariance for constraints of type parameters 828 p8: U // Contravariance for constraints of type parameters 829 ) 830 // Overriding kinds for return type 831 override kinds_of_return_type1(): Derived // Covariant return type 832 override kinds_of_return_type2(): (q: Base)=> Derived // Contravariant parameter type, covariant return type 833 override kinds_of_return_type3(): Number // Compile-time error: return type is not override-compatible 834 override kinds_of_return_type4(): number // Compile-time error: return type is not override-compatible 835 override kinds_of_return_type5(): Derived[] // Covariant array element type 836 override kinds_of_return_type6(): [Derived, Derived] // Covariant tuple type elements 837 override kinds_of_return_type7 <T extends Base> (): T // OK, contravariance for constraints of the return type 838 } 839 840The example below illustrates override-compatibility with ``Object``: 841 842.. code-block:: typescript 843 :linenos: 844 845 class Base { 846 kinds_of_parameters( // It represents all possible parameter type kinds 847 p1: Derived, p2: (q: Base)=>Derived, p3: number, 848 p4: Number, p5: Base[], p6: [Base, Base] 849 ) 850 kinds_of_return_type(): Object // It can be overridden by all subtypes except primitive ones 851 } 852 class Derived extends Base { 853 override kinds_of_parameters( // Object is a supertype for all types except primitive ones 854 p1: Object, p2: Object, 855 p3: Object, // Compile-time error: number and Object are not override-compatible 856 p4: Object, p5: Object, p6: Object 857 ) 858 class Derived1 extends Base { 859 override kinds_of_return_type(): Base // Valid overriding 860 } 861 class Derived2 extends Base { 862 override kinds_of_return_type(): (q: Derived)=> Base // Valid overriding 863 } 864 class Derived3 extends Base { 865 override kinds_of_return_type(): number // Compile-time error: number and Object are not override-compatible 866 } 867 class Derived4 extends Base { 868 override kinds_of_return_type(): Number // Valid overriding 869 } 870 class Derived5 extends Base { 871 override kinds_of_return_type(): Base[] // Valid overriding 872 } 873 class Derived6 extends Base { 874 override kinds_of_return_type(): [Base, Base] // Valid overriding 875 } 876 877| 878 879.. _Overloading for Functions: 880 881Overloading for Functions 882========================= 883 884*Overloading* must only be considered for functions because inheritance for 885functions is not defined. 886 887The correctness check for functions overloading is performed if two or more 888functions with the same name are accessible (see :ref:`Accessible`) in a scope 889(see :ref:`Scopes`). 890 891A function can be declared in, or imported to a scope. To prevent uncontrolled 892overloading, mixing functions that are declared and imported, or imported from 893different compilation units, is not allowed. In particular, a 894:index:`compile-time error` occurs to same-name functions if: 895 896- Functions are imported from different compilation units; 897 898- Some functions are imported, while others are declared. 899 900It means that only the functions declared in the scope can be overloaded. 901The semantic check for these functions is as follows: 902 903- If signatures of functions are *overload-equivalent*, then 904 a :index:`compile-time error` occurs. 905 906- Otherwise, *overloading* is valid. 907 908.. index:: 909 overloading 910 function 911 inheritance 912 access 913 scope 914 import 915 compilation unit 916 overload-equivalent signature 917 918| 919 920.. _Overloading and Overriding in Classes: 921 922Overloading and Overriding in Classes 923===================================== 924 925Both *overloading* and *overriding* must be considered in case of classes for 926methods and partly for constructors. 927 928**Note**: Only accessible (see :ref:`Accessible`) methods are subject for 929overloading and overriding. For example, neither overriding nor overloading 930is considered if a superclass contains a ``private`` method, and a subclass 931has a method with the same name. Accessors are considered methods here. 932 933An overriding member can keep or extend the access modifier (see 934:ref:`Access Modifiers`) of the inherited or implemented member. Otherwise, a 935:index:`compile-time error` occurs: 936 937.. index:: 938 overloading 939 inheritance 940 overriding 941 private 942 method 943 superclass 944 access modifier 945 946.. code-block:: typescript 947 :linenos: 948 949 class Base { 950 public public_member() {} 951 protected protected_member() {} 952 internal internal_member() {} 953 private private_member() {} 954 } 955 956 interface Interface { 957 public_member() // All members are public in interfaces 958 } 959 960 class Derived extends Base implements Interface { 961 public override public_member() {} 962 // Public member can be overridden and/or implemented by the public one 963 public override protected_member() {} 964 // Protected member can be overridden by the protected or public one 965 internal internal_member() {} 966 // Internal member can be overridden by the internal one only 967 override private_member() {} 968 // A compile-time error occurs if an attempt is made to override private member 969 } 970 971Semantic rules that work in various contexts are represented in the following 972table: 973 974+-------------------------------------+----------------------------------------------+ 975| **Context** | **Semantic Check** | 976+=====================================+==============================================+ 977| Two *instance methods*, | If signatures are *overload-equivalent*, | 978| two *static methods* with the same | (see :ref:`Overload-Equivalent Signatures`), | 979| name, or two *constructors* are | then a :index:`compile-time error` | 980| defined in the same class. | occurs. Otherwise, *overloading* is used. | 981+-------------------------------------+----------------------------------------------+ 982 983.. index:: 984 semantic check 985 instance method 986 method 987 static method 988 constructor 989 overload equivalence 990 overloading 991 overload-equivalent signature 992 993.. code-block:: typescript 994 :linenos: 995 996 class aClass { 997 998 instance_method_1() {} 999 instance_method_1() {} // compile-time error: instance method duplication 1000 1001 static static_method_1() {} 1002 static static_method_1() {} // compile-time error: static method duplication 1003 1004 instance_method_2() {} 1005 instance_method_2(p: number) {} // valid overloading 1006 1007 static static_method_2() {} 1008 static static_method_2(p: string) {} // valid overloading 1009 1010 constructor() {} 1011 constructor() {} // compile-time error: constructor duplication 1012 1013 constructor(p: number) {} 1014 constructor(p: string) {} // valid overloading 1015 1016 } 1017 1018+-------------------------------------+---------------------------------------------+ 1019| An *instance method* is defined | If signatures are *override-compatible* | 1020| in a subclass with the same name | (see :ref:`Override-Compatible Signatures`),| 1021| as the *instance method* in a | then *overriding* is used. | 1022| superclass. | Otherwise, *overloading* is used. | 1023+-------------------------------------+---------------------------------------------+ 1024 1025.. code-block:: typescript 1026 :linenos: 1027 1028 class Base { 1029 method_1() {} 1030 method_2(p: number) {} 1031 } 1032 class Derived extends Base { 1033 override method_1() {} // overriding 1034 method_2(p: string) {} // overloading 1035 } 1036 1037+-------------------------------------+---------------------------------------------+ 1038| A *static method* is defined | If signatures are *overload-equivalent* | 1039| in a subclass with the same name | (see :ref:`Overload-Equivalent Signatures`),| 1040| as the *static method* in a | then the static method in the subclass | 1041| superclass. | *hides* the previous static method. | 1042| | Otherwise, *overloading* is used. | 1043+-------------------------------------+---------------------------------------------+ 1044 1045.. index:: 1046 instance method 1047 static method 1048 subclass 1049 superclass 1050 override-compatible signature 1051 override-compatibility 1052 overloading 1053 hiding 1054 overriding 1055 1056.. code-block:: typescript 1057 :linenos: 1058 1059 class Base { 1060 static method_1() {} 1061 static method_2(p: number) {} 1062 } 1063 class Derived extends Base { 1064 static method_1() {} // hiding 1065 static method_2(p: string) {} // overloading 1066 } 1067 1068 1069+-------------------------------------+--------------------------------------------+ 1070| A *constructor* is defined | All base class constructors are available | 1071| in a subclass. | for call in all derived class constructors.| 1072+-------------------------------------+--------------------------------------------+ 1073 1074.. code-block:: typescript 1075 :linenos: 1076 1077 class Base { 1078 constructor() {} 1079 constructor(p: number) {} 1080 } 1081 class Derived extends Base { 1082 constructor(p: string) { 1083 super() 1084 super(5) 1085 } 1086 } 1087 1088.. index:: 1089 constructor 1090 subclass 1091 class constructor 1092 1093| 1094 1095.. _Overloading and Overriding in Interfaces: 1096 1097Overloading and Overriding in Interfaces 1098======================================== 1099 1100.. meta: 1101 frontend_status: Done 1102 1103+-------------------------------------+---------------------------------------------+ 1104| **Context** | **Semantic Check** | 1105+=====================================+=============================================+ 1106| A method is defined | If signatures are *override-compatible* | 1107| in a subinterface with the same | (see :ref:`Override-Compatible Signatures`),| 1108| name as the method in | then *overriding* is used. Otherwise, | 1109| the superinterface. | *overloading* is used. | 1110+-------------------------------------+---------------------------------------------+ 1111 1112.. code-block:: typescript 1113 :linenos: 1114 1115 interface Base { 1116 method_1() 1117 method_2(p: number) 1118 } 1119 interface Derived extends Base { 1120 method_1() // overriding 1121 method_2(p: string) // overloading 1122 } 1123 1124+-------------------------------------+------------------------------------------+ 1125| Two methods with the same | A :index:`compile-time error` occurs. | 1126| name are defined in the same | Otherwise, *overloading* is used. | 1127| interface. | | 1128+-------------------------------------+------------------------------------------+ 1129 1130.. index:: 1131 method 1132 subinterface 1133 superinterface 1134 semantic check 1135 override compatibility 1136 override-compatible signature 1137 1138.. code-block:: typescript 1139 :linenos: 1140 1141 interface anInterface { 1142 instance_method_1() 1143 instance_method_1() // Compile-time error: instance method duplication 1144 1145 instance_method_2() 1146 instance_method_2(p: number) // Valid overloading 1147 } 1148 1149| 1150 1151.. _Overload Resolution: 1152 1153Overload Resolution 1154******************* 1155 1156.. meta: 1157 frontend_status: Done 1158 1159The *overload resolution* is used to select one entity to call from a set of 1160*potentially applicable candidates* in a function, method, or constructor call. 1161 1162The overload resolution is performed in two steps as follows: 1163 1164#. Select *applicable candidates* from *potentially applicable candidates*; 1165 1166#. If there is more than one *applicable candidate*, then select the best 1167 candidate. 1168 1169**Note**: The first step is performed in all cases, even if there is 1170only one *applicable candidate* to check *call signature compatibility*. 1171 1172.. index:: 1173 overload resolution 1174 entity 1175 applicable candidate 1176 call signature compatibility 1177 1178| 1179 1180.. _Selection of Applicable Candidates: 1181 1182Selection of Applicable Candidates 1183================================== 1184 1185.. meta: 1186 frontend_status: Partly 1187 todo: adapt the implementation to the latest specification (handle rest, union, functional types properly) 1188 todo: make the ISA/assembler/runtime handle union types without collision - eg foo(arg: A|B) and foo(arg: C|D) 1189 1190The selection of *applicable candidates* is the process of checking 1191:ref:`Compatibility of Call Arguments` for all entities from the set of 1192*potentially applicable candidates*. If any argument is not compatible with 1193the corresponding parameter type, then the entity is deleted from the set. 1194 1195**Note**: Compile-time errors are not reported on this stage. 1196 1197After processing all entities, one of the following results is achieved: 1198 1199- Set is empty (all entities are deleted). A compile-time error occurs, 1200 and the *overload resolution* is completed. 1201 1202- Only one entity is left in the set. This is the entity to call, and 1203 the *overload resolution* is completed. 1204 1205- More than one entity is left in the set. The next step of the 1206 *overload resolution* is to be performed. 1207 1208.. index:: 1209 applicable candidate 1210 compatibility 1211 call argument 1212 parameter type 1213 overload resolution 1214 overloaded function 1215 1216Two overloaded functions are considered in the following example: 1217 1218.. code-block:: typescript 1219 :linenos: 1220 1221 class Base { } 1222 class Derived extends Base { } 1223 1224 function foo(p: Base) { ... } // #1 1225 function foo(p: Derived) { ... } // #2 1226 1227 foo(new Derived) // two applicable candidates for this call 1228 // next step of overload resolution is required 1229 1230 foo(new Base) // one applicable candidate 1231 // overload resolution is completed 1232 // #1 will be called 1233 1234 foo(new Base, 5) // no candidates, compile-time error 1235 1236| 1237 1238.. _Selection of Best Candidate: 1239 1240Selection of Best Candidate 1241=========================== 1242 1243.. meta: 1244 frontend_status: Partly 1245 1246If the set of *applicable candidates* has two or more candidates, then the 1247best candidate for the given list of arguments is to be identified, if possible. 1248 1249The selection of the best candidate is based on the following: 1250 1251- There are no candidates with the same list of parameters, as this situation 1252 is already forbidden by the compiler (on declaration or import site); 1253 1254- If several candidates can be called correctly by using the same argument list, 1255 then the same implicit argument transformations must be applied to make the 1256 call. 1257 1258Possible argument transformations are listed below: 1259 1260- :ref:`Implicit Conversions`; 1261 1262- Passing default values to fill any missing arguments 1263 (:ref:`Optional Parameters`); 1264 1265- Passing the empty array to replace a rest parameter that has no argument; 1266 1267- Folding several arguments to the array for a rest parameter. 1268 1269.. index:: 1270 applicable candidate 1271 best candidate 1272 parameter 1273 compiler 1274 import site 1275 argument transformation 1276 value 1277 rest parameter 1278 1279The examples of transformations are presented below: 1280 1281.. code-block:: typescript 1282 :linenos: 1283 1284 function foo1(x: number) {} 1285 foo1(1) // implicit conversion int -> double 1286 1287 function foo2(x: Int) {} 1288 foo2(1) // implicit boxing 1289 1290 function foo3(x?: string) {} 1291 foo3() // passing default value -> foo(undefined) 1292 1293 function foo4(...x: int[]) {} 1294 foo4() // passing empty array -> foo([]) 1295 foo4(1, 2) // folding to array -> foo(...[1, 2]) 1296 1297The candidate that does not require transformations for all arguments is the 1298*best candidate*. Other candidates are not considered. 1299 1300The examples below represent the best candidate selected without 1301transformation: 1302 1303.. code-block:: typescript 1304 :linenos: 1305 1306 function foo(i: int) // #1 1307 function foo(n: number) // #2 1308 1309 let x: int = 1 1310 foo(x) // #1 - is the best candidate, no transformations 1311 1312 function goo(s: string) // #1 1313 function goo(s?: string) // #2 1314 1315 goo("abc") // #1 - is the best candidate, no transformations 1316 1317 let x: string|undefined = "abc" 1318 goo(x) // #2 - is the best candidate, no transformations 1319 1320.. index:: 1321 best candidate 1322 transformation 1323 argument 1324 1325If there is no such candidate, then each argument transformation of each 1326candidate is compared (taking optional and rest parameters into the account) 1327by calculating partial *better* relation: 1328 1329**Case 1**. No transformation is *better* than any transformation. 1330 1331**Case 2**. If argument type is of a numeric type, char, or its boxed 1332counterpart, then the candidate with a *shorter* conversion is *better*. E.g., 1333the conversion of ``int`` to ``float`` is *better* than ``int`` to ``double``, 1334and ``int`` to ``Int`` is *better* than ``int`` to ``Long``. 1335 1336**Case 3**. In case of optional parameters, no parameter is *better*. 1337 1338**Case 4**. If the first candidate has several parameters, and the other 1339candidate has a rest parameter for the same arguments, then the first one 1340is *better*. 1341 1342**Case 5**. All other variants are considered *not comparable*. 1343 1344.. index:: 1345 best candidate 1346 argument transformation 1347 numeric type 1348 char 1349 boxing 1350 conversion 1351 parameter 1352 1353.. code-block:: typescript 1354 :linenos: 1355 1356 // Case 1: 1357 function foo(n: number, s: string|null) // #1 1358 function foo(n: number, s: string) // #2 1359 1360 goo(1, "abc") // #2 is better, no transformation for 2nd argument 1361 1362 // Case 2: 1363 function foo(i: long) // #1 1364 function foo(n: float) // #2 1365 1366 let x: int = 1 1367 foo(x) // #1 is better, conversion is shorter 1368 1369 // Case 3: 1370 function foo(n: number, s?: string) // #1 1371 function foo(n: number) // #2 1372 1373 foo(1) // #2 is better, less parameters 1374 1375 // Case 4: 1376 function foo(sum: number, a: number, b: number) // #1 1377 function foo(sum: number, ...x: number[]) // #2 1378 1379 foo(1, 2, 3) // #1 is better, non-rest parameters 1380 1381 // Case 5: 1382 class Base { } 1383 class Derived extends Base { } 1384 1385 function foo(p: Base) { ... } // #1 1386 function foo(p: Derived) { ... } // #2 1387 1388 foo(new Derived) // not comparable, no one is better 1389 1390If there is exactly one candidate that is *better* than others for at least 1391one argument and *not comparable* to other arguments, then this one is the 1392*best candidate* that is to be called. 1393 1394If no candidate is the *best candidate*, then a :index:`compile-time error` 1395occurs. Examples of error cases are presented below: 1396 1397.. code-block:: typescript 1398 :linenos: 1399 1400 class Base { } 1401 class Derived extends Base { } 1402 1403 function foo(p: Base) { ... } // #1 1404 function foo(p: Derived) { ... } // #2 1405 1406 foo(new Derived) // compile-time error, as 1407 // there is no argument where one candidate is better 1408 1409 function goo(a: int; b: float) // #1 1410 function goo(a: float, b: int) // #2 1411 1412 goo(1, 1) // compile-time error, as 1413 // #1 is better for 1st argument, 1414 // #2 is better for 2nd argument. 1415 1416.. index:: 1417 best candidate 1418 argument 1419 1420| 1421 1422.. _Overload Signatures: 1423 1424Overload Signatures 1425******************* 1426 1427|LANG| supports *overload signatures* to ensure better |TS| alignment for 1428functions (:ref:`Function Overload Signatures`), static and instance methods 1429(:ref:`Method Overload Signatures`), and constructors 1430(:ref:`Constructor Overload Signatures`). 1431 1432All signatures except the last *implementation signature* are considered 1433*syntactic sugar*. The compiler uses the *implementation signature* only 1434as it considers overloading, overriding, shadowing, or calls. 1435 1436.. index:: 1437 overload signature 1438 alignment 1439 constructor 1440 implementation signature 1441 syntactic sugar 1442 signature 1443 overloading 1444 overriding 1445 shadowing 1446 call 1447 1448| 1449 1450.. _Overload Signature Correctness Check: 1451 1452Overload Signature Correctness Check 1453==================================== 1454 1455If a function, method, or constructor has several *overload signatures* 1456that share the same body, then all first signatures without bodies must 1457*fit* into the *implementation signature* that has the body. Otherwise, 1458a :index:`compile-time error` occurs. 1459 1460Signature *S*:sub:`i` with *n* parameters *fits* into implementation signature 1461*IS* if **all** of the following conditions are met: 1462 1463- *S*:sub:`i` has *n* parameters, *IS* has *m* parameters, and: 1464 1465 - ``n <= m``; 1466 - All ``n`` parameter types in *S*:sub:`i` are compatible (see 1467 :ref:`Type Compatibility`) with parameter types in the same positions 1468 in *IS*:sub:`2`; 1469 - All *IS* parameters in positions from ``n + 1`` up to ``m`` are optional 1470 (see :ref:`Optional Parameters`) if ``n < m``. 1471 1472- *IS* return type is ``void`` (see :ref:`Type void`), then *S*:sub:`i` return 1473 type must also be ``void``. 1474 1475- *IS* return type is not ``void``, then *S*:sub:`i` return type must be 1476 ``void`` (see :ref:`Type void`) or compatible with the return type of *IS* 1477 (see :ref:`Type Compatibility`). 1478 1479.. index:: 1480 overload signature 1481 correctness check 1482 parameter 1483 implementation signature 1484 function 1485 method 1486 constructor 1487 compatibility 1488 return type 1489 1490The examples below represent valid overload signatures: 1491 1492.. code-block-meta: 1493 expect-cte: 1494 1495.. code-block:: typescript 1496 :linenos: 1497 1498 function f1(): void 1499 function f1(x: number): void 1500 function f1(x?: number): void { 1501 /*body*/ 1502 } 1503 1504 function f2(x: number): void 1505 function f2(x: string): void 1506 function f2(x: number | string): void { 1507 /*body*/ 1508 } 1509 1510 function f3(x: number): void 1511 function f3(x: string): number 1512 function f3(x: number | string): number { 1513 return 1 1514 } 1515 1516The examples below represent code with compile-time errors: 1517 1518.. code-block:: typescript 1519 :linenos: 1520 1521 function f4(x: number): void 1522 function f4(x: boolean): number // This signature does not fit 1523 function f4(x: number | string): void { 1524 /*body*/ 1525 } 1526 1527 function f5(x: number): void 1528 function f5(x: string): number // Wrong return type 1529 function f5(x: number | string): void { 1530 /*body*/ 1531 } 1532 1533| 1534 1535.. _Compatibility Features: 1536 1537Compatibility Features 1538********************** 1539 1540Some features are added to |LANG| in order to support smooth |TS| compatibility. 1541Using these features while doing the |LANG| programming is not recommended in 1542most cases. 1543 1544.. index:: 1545 overload signature compatibility 1546 compatibility 1547 1548| 1549 1550.. _Extended Conditional Expressions: 1551 1552Extended Conditional Expressions 1553================================ 1554 1555.. meta: 1556 frontend_status: Done 1557 1558|LANG| provides extended semantics for conditional expressions 1559to ensure better |TS| alignment. 1560It affects the semantics of 1561 1562- Conditional expressions (see :ref:`Conditional Expressions`, 1563 :ref:`Conditional-And Expression`, :ref:`Conditional-Or Expression`, and 1564 :ref:`Logical Complement`); 1565 1566- ``while`` and ``do`` statements (see :ref:`While Statements and Do Statements`); 1567 1568- ``for`` statements (see :ref:`For Statements`); 1569 1570- ``if`` statements (see :ref:`if Statements`); 1571 1572- assignment (see :ref:`Simple Assignment Operator`). 1573 1574**Note:** The extended semantics is to be deprecated in one of the future 1575versions of the language. 1576 1577This approach is based on the concept of *truthiness* that extends the Boolean 1578logic to operands of non-Boolean types. 1579 1580Depending on the kind of the value type, the value of any valid expression can 1581be handled as ``true`` or ``false`` as described in the table below: 1582 1583.. index:: 1584 extended conditional expression 1585 semantic alignment 1586 conditional-and expression 1587 conditional-or expression 1588 conditional expression 1589 while statement 1590 do statement 1591 for statement 1592 if statement 1593 truthiness 1594 Boolean 1595 value type 1596 1597+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1598| Value Type | When ``false`` | When ``true`` | |LANG| Code | 1599+======================================+========================================+===================================+=================================+ 1600| ``string`` | empty string | non-empty string | ``s.length == 0`` | 1601+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1602| ``boolean`` | ``false`` | ``true`` | ``x`` | 1603+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1604| ``enum`` | ``enum`` constant | enum constant | ``x.getValue()`` | 1605| | | | | 1606| | handled as ``false`` | handled as ``true`` | | 1607+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1608| ``number`` (``double``/``float``) | ``0`` or ``NaN`` | any other number | ``n != 0 && n != NaN`` | 1609+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1610| any integer type | ``== 0`` | ``!= 0`` | ``i != 0`` | 1611+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1612| ``char`` | ``== 0`` | ``!= 0`` | ``c != c'0'`` | 1613+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1614| let T - is any nonNullish type | 1615+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1616| ``T | null`` | ``== null`` | ``!= null`` | ``x != null`` | 1617+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1618| ``T | undefined`` | ``== undefined`` | ``!= undefined`` | ``x != undefined`` | 1619+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1620| ``T | undefined | null`` | ``== undefined`` or ``== null`` | ``!= undefined`` and ``!= null`` | ``x != undefined && x != null`` | 1621+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1622| Boxed primitive type | primitive type is ``false`` | primitive type is ``true`` | ``new Boolean(true) == true`` | 1623| (``Boolean``, ``Char``, ``Int`` ...) | | | ``new Int (0) == 0`` | 1624+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1625| any other nonNullish type | ``never`` | ``always`` | ``new SomeType != null`` | 1626+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+ 1627 1628Extended semantics of :ref:`Conditional-And Expression` and 1629:ref:`Conditional-Or Expression` affects the resultant type of expressions 1630as follows: 1631 1632- A *conditional-and* expression ``A && B`` is of type ``B`` if the result of 1633 ``A`` is handled as ``true``. Otherwise, it is of type ``A``. 1634 1635- A *conditional-or* expression ``A || B`` is of type ``B`` if the result of 1636 ``A`` is handled as ``false``. Otherwise, it is of type ``A``. 1637 1638 1639The example below illustrates the way this approach works in practice. Any 1640``nonzero`` number is handled as ``true``. The loop continues until it becomes 1641``zero`` that is handled as ``false``: 1642 1643.. code-block-meta: 1644 1645.. code-block:: typescript 1646 :linenos: 1647 1648 for (let i = 10; i; i--) { 1649 console.log (i) 1650 } 1651 /* And the output will be 1652 10 1653 9 1654 8 1655 7 1656 6 1657 5 1658 4 1659 3 1660 2 1661 1 1662 */ 1663 1664.. index:: 1665 NaN 1666 nullish expression 1667 numeric expression 1668 conditional-and expression 1669 conditional-or expression 1670 loop 1671 1672 1673.. raw:: pdf 1674 1675 PageBreak 1676 1677 1678