• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1..
2    Copyright (c) 2021-2025 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 this Specification
22document. The description of the rules is more or less informal. Some details
23are omitted to simplify the understanding.
24
25.. index::
26   semantic rule
27
28|
29
30.. _Semantic Essentials:
31
32Semantic Essentials
33*******************
34
35The section gives a brief introduction to the major semantic terms
36and their usage in several contexts.
37
38|
39
40.. _Type of Standalone Expression:
41
42Type of Standalone Expression
43=============================
44
45*Standalone expression* (see :ref:`Type of Expression`) is an expression for
46which no target type is expected in its context.
47
48The type of a *standalone expression* is determined as follows:
49
50- In case of :ref:`Numeric Literals`, the type is the default type of a literal:
51
52    - Type of :ref:`Integer Literals` is ``int`` or ``long``;
53    - Type of :ref:`Floating-Point Literals` is ``double`` or ``float``.
54
55- In case of :ref:`Constant Expressions`, the type is inferred from operand
56  types and operations.
57
58- In case of an :ref:`Array Literal`, the type is inferred from the elements
59  (see :ref:`Array Type Inference from Types of Elements`).
60
61- Otherwise, a :index:`compile-time error` occurs. Specifically,
62  a :index:`compile-time error` occurs if an *object literal* is used
63  as a *standalone expression*.
64
65The situation is represented by the example below:
66
67.. code-block:: typescript
68   :linenos:
69
70    function foo() {
71      1    // type is 'int'
72      1.0  // type is 'number'
73      [1.0, 2.0]  // type is number[]
74      [1, "aa"] // type is (int | string)
75    }
76
77|
78
79.. Specifics of Assignment-like Contexts:
80
81Specifics of Assignment-like Contexts
82=====================================
83
84*Assignment-like context* (see :ref:`Assignment-like Contexts`) can be
85considered as an assignment ``x = expr``, where ``x`` is a left-hand-side
86expression, and ``expr`` is a right-hand-side expression. E.g., there is an
87implicit assignment of ``expr`` to the formal parameter ``foo`` in the call
88``foo(expr)``, and implicit assignments to elements or properties in
89:ref:`Array Literal` and :ref:`Object Literal`.
90
91*Assignment-like context* is specific in that the type of a left-hand-side
92expression is known, but the type of a right-hand-side expression is not
93necessarily known in the context as follows:
94
95-  If the type of a right-hand-side expression is known from the expression
96   itself, then the :ref:`Assignability` check is performed as in the example
97   below:
98
99.. code-block:: typescript
100   :linenos:
101
102    function foo(x: string, y: string) {
103        x = y // ok, assignability is checked
104    }
105
106-  Otherwise, an attempt is made to apply the type of the left-hand-side
107   expression to the right-hand-side expression. A :index:`compile-time error`
108   occurs if the attempt fails as in the example below:
109
110.. code-block:: typescript
111   :linenos:
112
113    function foo(x: int, y: double[]) {
114        x = 1 // ok, type of '1' is inferred from type of 'x'
115        y = [1, 2] // ok, array literal is evaluated as [1.0, 2.0]
116    }
117
118|
119
120.. Specifics of Variable Initialization Context:
121
122Specifics of Variable Initialization Context
123============================================
124
125If the variable or a constant declaration (see
126:ref:`Variable and Constant Declarations`) has an explicit type annotation,
127then the same rules as for *assignment-like contexts* apply. Otherwise, there
128are two cases for ``let x = expr`` (see :ref:`Type Inference from Initializer`)
129as follows:
130
131-  The type of the right-hand-side expression is known from the expression
132   itself, then this type becomes the type of the variable as in the example
133   below:
134
135.. code-block:: typescript
136   :linenos:
137
138    function foo(x: int) {
139        let x = y // type of 'x' is 'int'
140    }
141
142-  Otherwise, the type of ``expr`` is evaluated as type of a standalone
143   expression as in the example below:
144
145.. code-block:: typescript
146   :linenos:
147
148    function foo() {
149        let x = 1 // x is of type 'int' (default type of '1')
150        let y = [1, 2] // x is of type 'number[]'
151    }
152
153|
154
155.. _Specifics of Numeric Operator Contexts:
156
157Specifics of Numeric Operator Contexts
158======================================
159
160Operands of unary and binary numeric expressions are widened to a larger numeric
161type. The minimum type is ``int``. Specifically, no arithmetic operator
162evaluates values of types ``byte`` and ``short`` without widening. Details of
163specific operators are discussed in corresponding sections of the Specification.
164
165|
166
167.. _Specifics of String Operator Contexts:
168
169Specifics of String Operator Contexts
170=====================================
171
172If one operand of the binary operator ‘`+`’ is of type ``string``, then the
173string conversion applies to another non-string operand to convert it to string
174(see :ref:`String Concatenation` and :ref:`String Operator Contexts`).
175
176|
177
178.. _Other Contexts:
179
180Other Contexts
181==============
182
183The only semantic rule for all other contexts, and specifically for
184:ref:`Overloading and Overriding`, is to use :ref:`Subtyping`.
185
186|
187
188.. _Specifics of Type Parameters:
189
190Specifics of Type Parameters
191============================
192
193If the type of a left-hand-side expression in *assignment-like context* is a
194type parameter, then it provides no additional information for type inference
195even where a type parameter constraint is set.
196
197If the *target type* of an expression is a *type parameter*, then the type of
198the expression is inferred as the type of a *standalone expression*.
199
200The semantics is represented by the example below:
201
202.. code-block:: typescript
203   :linenos:
204
205    class C<T extends number> {
206        constructor (x: T) {}
207    }
208
209    new C(1) // compile-time error
210
211The type of '``1``' in the example above is inferred as ``int`` (default type of
212an integer literal). The expression is considered ``new C<int>(1)`` and causes
213a :index:`compile-time error` because ``int`` is not a subtype of ``number``
214(type parameter constraint).
215
216Explicit type argument ``new C<number>(1)`` must be used to fix the code.
217
218|
219
220.. _Semantic Essentials Summary:
221
222Semantic Essentials Summary
223===========================
224
225Major semantic terms are listed below:
226
227- :ref:`Type of Expression`;
228- :ref:`Assignment-like Contexts`;
229- :ref:`Type Inference from Initializer`;
230- :ref:`Numeric Operator Contexts`;
231- :ref:`String Operator Contexts`;
232- :ref:`Subtyping`;
233- :ref:`Assignability`;
234- :ref:`Overloading and Overriding`;
235- :ref:`Type Inference`.
236
237|
238
239.. _Subtyping:
240
241Subtyping
242*********
243
244.. meta:
245    frontend_status: Done
246
247*Subtype* relationship between types ``S`` and ``T``, where ``S`` is a
248subtype of ``T`` (recorded as ``S<:T``), means that any object of type
249``S`` can be safely used in any context to replace an object of type ``T``.
250The opposite relation (recorded as ``T:>S``) is called *supertype* relationship.
251Each type is its own subtype and supertype (``S<:S``).
252
253By the definition of ``S<:T``, type ``T`` belongs to the set of *supertypes*
254of type ``S``. The set of *supertypes* includes all *direct supertypes*
255(discussed in subsections), and all their respective *supertypes*.
256More formally speaking, the set is obtained by reflexive and transitive
257closure over the direct supertype relation.
258
259If the subtyping relation of two types is not defined in a section below,
260then such types are not related to each other. Specifically, two array types
261(resizable and fixed-size alike), and two tuple types are not related to each
262other, except where they are identical (see :ref:`Type Identity`).
263
264.. index::
265   subtyping
266   subtype
267   closure
268   supertype
269   direct supertype
270   reflexive closure
271   transitive closure
272   array type
273   array
274   resizable array
275   fixed-size array
276   tuple type
277   type
278
279|
280
281.. _Subtyping for Classes and Interfaces:
282
283Subtyping for Classes and Interfaces
284====================================
285
286.. meta:
287    frontend_status: Partly
288
289Terms *subclass*, *subinterface*, *superclass*, and *superinterface* are used
290when considering class or interface types.
291
292*Direct supertypes* of a non-generic class, or of the interface type ``C``
293are **all** of the following:
294
295-  Direct superclass of ``C`` (as mentioned in its extension clause, see
296   :ref:`Class Extension Clause`) or type ``Object`` if ``C`` has no extension
297   clause specified;
298
299-  Direct superinterfaces of ``C`` (as mentioned in the implementation
300   clause of ``C``, see :ref:`Class Implementation Clause`); and
301
302-  Class ``Object`` if ``C`` is an interface type with no direct superinterfaces
303   (see :ref:`Superinterfaces and Subinterfaces`).
304
305.. index::
306   subclass
307   subinterface
308   superclass
309   superinterface
310   interface type
311   direct supertype
312   non-generic class
313   direct superclass
314   direct superinterface
315   implementation
316   non-generic class
317   extension clause
318   implementation clause
319   superinterface
320   Object
321   interface type
322   direct superinterface
323   class extension
324   subinterface
325
326*Direct supertypes* of the generic type ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>
327(for a generic class or interface type declaration ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>
328with *n*>0) are **all** of the following:
329
330-  Direct superclass of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>;
331
332-  Direct superinterfaces of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>, and
333
334-  Type ``Object`` if ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`> is a generic
335   interface type with no direct superinterfaces.
336
337The direct supertype of a type parameter is the type specified as the
338constraint of that type parameter.
339
340.. index::
341   direct supertype
342   generic type
343   generic class
344   generic interface
345   interface type declaration
346   direct superinterface
347   type parameter
348   superclass
349   supertype
350   type
351   constraint
352   type parameter
353   superinterface
354   bound
355   Object
356
357|
358
359
360.. _Subtyping for Literal Types:
361
362Subtyping for Literal Types
363===========================
364
365.. meta:
366    frontend_status: Done
367
368Any ``string`` literal type (see :ref:`Literal Types`) is *subtype* of type
369``string``. It affects overriding as shown in the example below:
370
371.. code-block:: typescript
372   :linenos:
373
374    class Base {
375        foo(p: "1"): string { return "42" }
376    }
377    class Derived extends Base {
378        override foo(p: string): "1" { return "1" }
379    }
380    // Type "1" <: string
381
382    let base: Base = new Derived
383    let result: string = base.foo("1")
384    /* Argument "1" (value) is compatible to type "1" and to type string in
385       the overridden method
386       Function result of type string accepts "1" (value) of literal type "1"
387    */
388
389Literal type ``null`` (see :ref:`Literal Types`) is a subtype and a supertype to
390itself. Similarly, literal type ``undefined`` is a subtype and a supertype to
391itself.
392
393.. index::
394   literal type
395   subtype
396   type string
397   overriding
398   supertype
399   string literal
400   null
401   undefined
402   literal type
403
404|
405
406.. _Subtyping for Union Types:
407
408Subtyping for Union Types
409=========================
410
411.. meta:
412    frontend_status: Done
413
414A union type ``U`` participates in subtyping relations
415(see :ref:`Subtyping`) in the following cases:
416
4171. Union type ``U`` (``U``:sub:`1` ``| ... | U``:sub:`n`) is a subtype of
418type ``T`` if each ``U``:sub:`i` is a subtype of ``T``.
419
420.. code-block:: typescript
421   :linenos:
422
423    let s1: "1" | "2" = "1"
424    let s2: string = s1 // ok
425
426    let a: string | number | boolean = "abc"
427    let b: string | number = 42
428    a = b // OK
429    b = a // compile-time error, boolean is absent is 'b'
430
431    class Base {}
432    class Derived1 extends Base {}
433    class Derived2 extends Base {}
434
435    let x: Base = ...
436    let y: Derived1 | Derived2 = ...
437
438    x = y // OK, both Derived1 and Derived2 are subtypes of Base
439    y = x // compile-time error
440
441    let x: Base | string = ...
442    let y: Derived1 | string ...
443    x = y // OK, Derived1 is subtype of Base
444    y = x // compile-time error
445
446.. index::
447   union type
448   subtyping
449   subtype
450   type
451
4522. Type ``T`` is a subtype of union type ``U``
453(``U``:sub:`1` ``| ... | U``:sub:`n`) if for some ``i``
454``T`` is a subtype of ``U``:sub:`i`.
455
456.. code-block:: typescript
457   :linenos:
458
459    let u: number | string = 1 // ok
460    u = "aa" // ok
461    u = 1.0  // ok, 1.0 is of type 'number' (double)
462    u = 1    // compile-time error, type 'int' is not a subtype of 'number'
463    u = true // compile-time error
464
465**Note**. If union type normalization produces a single type, then this type
466is used instead of the initial set of union types. This concept is represented
467by the example below:
468
469.. index::
470   union type
471   normalization
472   subtype
473
474.. code-block:: typescript
475   :linenos:
476
477    let u: "abc" | "cde" | string // type of 'u' is string
478
479|
480
481.. _Subtyping for Function Types:
482
483Subtyping for Function Types
484============================
485
486.. meta:
487    frontend_status: Done
488
489Function type ``F`` with parameters ``FP``:sub:`1` ``, ... , FP``:sub:`m`
490and return type ``FR``  is a *subtype* of function type ``S`` with parameters
491``SP``:sub:`1` ``, ... , SP``:sub:`n` and return type ``SR`` if **all** of the
492following conditions are  met:
493
494-  ``m <= n``
495
496-  for each ``i <= m``
497
498   -  Parameter type of ``SP``:sub:`i` is a subtype of
499      parameter type of ``FP``:sub:`i` (contravariance), and
500
501   -  ``FP``:sub:`i` is a rest parameter if ``SP``:sub:`i` is a rest parameter.
502   -  ``FP``:sub:`i` is an optional parameter if ``SP``:sub:`i` is an optional
503      parameter.
504
505-  ``FR`` can be any type if ``SR`` is type ``void``. Otherwise, the resultant
506   type ``FR`` is a subtype of ``SR`` (covariance).
507
508.. index::
509   function type
510   subtype
511   parameter type
512   contravariance
513   rest parameter
514   parameter
515   covariance
516   return type
517
518.. code-block:: typescript
519   :linenos:
520
521    class Base {}
522    class Derived extends Base {}
523
524    function check(
525       bb: (p: Base) => Base,
526       bd: (p: Base) => Derived,
527       db: (p: Derived) => Base,
528       dd: (p: Derived) => Derived
529    ) {
530       bb = bd
531       /* OK: identical parameter types, and covariant return type */
532       bb = dd
533       /* Compile-time error: parameter type are not contravariant */
534       db = bd
535       /* OK: contravariant parameter types, and covariant  return type */
536
537       let f: (p: Base, n: number) => Base = bb
538       /* OK: subtype has less parameters */
539
540       let g: () => Base = bb
541       /* Compile-time error: too less parameters */
542
543       let h: (p: Base) => void = bb
544       /* OK: result type of supertype is void */
545    }
546
547.. index::
548   parameter type
549   covariance
550   contravariance
551   covariant return type
552   contravariant return type
553   supertype
554   parameter
555
556|
557
558.. _Type Identity:
559
560Type Identity
561*************
562
563.. meta:
564    frontend_status: Done
565
566*Identity* relation between two types means that the types are
567indistinguishable. Identity relation is symmetric and transitive.
568Identity relation for types ``A`` and ``B`` is defined as follows:
569
570- Array types ``A`` = ``T1[]`` and ``B`` = ``Array<T2>`` are identical
571  if ``T1`` and ``T2`` are identical.
572
573- Tuple types ``A`` = [``T``:sub:`1`, ``T``:sub:`2`, ``...``, ``T``:sub:`n`] and
574  ``B`` = [``U``:sub:`1`, ``U``:sub:`2`, ``...``, ``U``:sub:`m`]
575  are identical if the following conditions are met:
576
577  - ``n`` is equal to ``m``, i.e., the types have the same number of elements;
578  - Every *T*:sub:`i` is identical to *U*:sub:`i` for any *i* in ``1 .. n``.
579
580- Union types ``A`` = ``T``:sub:`1` | ``T``:sub:`2` | ``...`` | ``T``:sub:`n` and
581  ``B`` = ``U``:sub:`1` | ``U``:sub:`2` | ``...`` | ``U``:sub:`m`
582  are identical if the following conditions are met:
583
584  - ``n`` is equal to ``m``, i.e., the types have the same number of elements;
585  - *U*:sub:`i` in ``U`` undergoes a permutation after which every *T*:sub:`i`
586    is identical to *U*:sub:`i` for any *i* in ``1 .. n``.
587
588- Types ``A`` and ``B`` are identical if ``A`` is a subtype of ``B`` (``A<:B``),
589  and ``B`` is  at the same time a subtype of ``A`` (``A:>B``).
590
591**Note.** :ref:`Type Alias Declaration` creates no new type but only a new
592name for the existing type. An alias is indistinguishable from its base type.
593
594.. index::
595   type identity
596   identity
597   indistinguishable type
598   array type
599   tuple type
600   union type
601   subtype
602   type
603   type alias
604   declaration
605   base type
606
607|
608
609.. _Assignability:
610
611Assignability
612*************
613
614.. meta:
615    frontend_status: Done
616
617Type ``T``:sub:`1` is assignable to type ``T``:sub:`2` if:
618
619-  ``T``:sub:`1` is type ``never`` and ``T``:sub:`2` is any other type;
620
621-  ``T``:sub:`1` is identical to ``T``:sub:`2` (see :ref:`Type Identity`);
622
623-  ``T``:sub:`1` is a subtype of ``T``:sub:`2` (see :ref:`Subtyping`); or
624
625-  *Implicit conversion* (see :ref:`Implicit Conversions`) is present that
626   allows converting a value of type ``T``:sub:`1` to type ``T``:sub:`2`.
627
628
629*Assignability* relationship  is asymmetric, i.e., that ``T``:sub:`1`
630is assignable to ``T``:sub:`2` does not imply that ``T``:sub:`2` is
631assignable to type ``T``:sub:`1`.
632
633.. index::
634   assignability
635   type
636   type identity
637   subtyping
638   conversion
639   implicit conversion
640   asymmetric relationship
641
642|
643
644.. _Invariance, Covariance and Contravariance:
645
646Invariance, Covariance and Contravariance
647*****************************************
648
649.. meta:
650    frontend_status: Done
651
652*Variance* is how subtyping between types relates to subtyping between
653derived types, including generic types (See :ref:`Generics`), member
654signatures of generic types (type of parameters, return type),
655and overriding entities (See :ref:`Override-Compatible Signatures`).
656Variance can be of three kinds:
657
658-  Covariance,
659-  Contravariance, and
660-  Invariance.
661
662.. index::
663   variance
664   subtyping
665   type
666   subtyping
667   derived type
668   generic type
669   generic
670   signature
671   type parameter
672   overriding entity
673   override-compatible signature
674   parameter
675   return type
676   variance
677   invariance
678   covariance
679   contravariance
680
681*Covariance* means it is possible to use a type which is more specific than
682originally specified.
683
684.. index::
685   covariance
686
687*Contravariance* means it is possible to use a type which is more general than
688originally specified.
689
690.. index::
691   contravariance
692
693*Invariance* means it is only possible to use the original type, i.e., there is
694no subtyping for derived types.
695
696.. index::
697   invariance
698
699The examples below illustrate valid and invalid usages of variance.
700If class ``Base`` is defined as follows:
701
702.. index::
703   variance
704   base class
705
706.. code-block:: typescript
707   :linenos:
708
709   class Base {
710      method_one(p: Base): Base {}
711      method_two(p: Derived): Base {}
712      method_three(p: Derived): Derived {}
713   }
714
715---then the code below is valid:
716
717.. code-block:: typescript
718   :linenos:
719
720   class Derived extends Base {
721      // invariance: parameter type and return type are unchanged
722      override method_one(p: Base): Base {}
723
724      // covariance for the return type: Derived is a subtype of Base
725      override method_two(p: Derived): Derived {}
726
727      // contravariance for parameter types: Base is a supertype for Derived
728      override method_three(p: Base): Derived {}
729   }
730
731.. index::
732   variance
733   subtype
734   base
735   overriding
736   method
737
738On the contrary, the following code causes compile-time errors:
739
740.. code-block-meta:
741   expect-cte
742
743.. code-block:: typescript
744   :linenos:
745
746   class Derived extends Base {
747
748      // covariance for parameter types is prohibited
749      override method_one(p: Derived): Base {}
750
751      // contravariance for the return type is prohibited
752      override method_tree(p: Derived): Base {}
753   }
754
755|
756
757.. _Compatibility of Call Arguments:
758
759Compatibility of Call Arguments
760*******************************
761
762.. meta:
763    frontend_status: Done
764
765
766The following semantic checks must be performed to arguments from the left to
767the right when checking the validity of any function, method, constructor, or
768lambda call:
769
770**Step 1**: All arguments in the form of spread expression (see
771:ref:`spread Expression`) are to be linearized recursively to enusre that
772no spread expression is left at the call site.
773
774**Step 2**: The following checks are performed on all arguments from left to
775right, starting from ``arg_pos`` = 1 and ``par_pos`` = 1:
776
777   if parameter at position ``par_pos`` is of non-rest form, then
778
779      if `T`:sub:`arg_pos` <: `T`:sub:`par_pos`, then increment ``arg_pos`` and ``par_pos``
780      else a :index:`compile-time error` occurs, exit Step 2
781
782   else // parameter is of rest form (see :ref:`Rest Parameter`)
783
784      if parameter is of rest_array_form, then
785
786         if `T`:sub:`arg_pos` <: `T`:sub:`rest_array_type`, then increment ``arg_pos``
787         else increment ``par_pos``
788
789      else // parameter is of rest_tuple_form
790
791         for `rest_tuple_pos` in 1 .. rest_tuple_types.count do
792
793            if `T`:sub:`arg_pos` <: `T`:sub:`rest_tuple_pos`, then increment ``arg_pos`` and `rest_tuple_pos`
794            else if rest_tuple_pos < rest_tuple_types.count, then increment ``rest_tuple_pos``
795            else a :index:`compile-time error` occurs, exit Step 2
796
797         end
798         increment ``par_pos``
799
800      end
801
802   end
803
804.. index::
805   assignability
806   compatibility
807   semantic check
808   function call
809   method call
810   constructor call
811   function
812   method
813   constructor
814   rest parameter
815   parameter
816   spread operator
817   spread expression
818   array
819   tuple
820   argument type
821   expression
822   operator
823   assignable type
824   increment
825   array type
826   rest parameter
827
828The examples below represent the checks:
829
830.. code-block:: typescript
831   :linenos:
832
833    call (...[1, "str", true], ...[ ...123])  // Initial call form
834
835    call (1, "str", true, 123) // To be unfoled into the form with no spread expressions
836
837
838
839    function foo1 (p: Object) {}
840    foo1 (1)  // Type of '1' must be assignable to 'Object'
841              // p becomes 1
842
843    function foo2 (...p: Object[]) {}
844    foo2 (1, "111")  // Types of '1' and "111" must be assignable to 'Object'
845              // p becomes array [1, "111"]
846
847    function foo31 (...p: (number|string)[]) {}
848    foo31 (...[1, "111"])  // Type of array literal [1, "111"] must be assignable to (number|string)[]
849              // p becomes array [1, "111"]
850
851    function foo32 (...p: [number, string]) {}
852    foo32 (...[1, "111"])  // Types of '1' and "111" must be assignable to 'number' and 'string' accordingly
853              // p becomes tuple [1, "111"]
854
855    function foo4 (...p: number[]) {}
856    foo4 (1, ...[2, 3])  //
857              // p becomes array [1, 2, 3]
858
859    function foo5 (p1: number, ...p2: number[]) {}
860    foo5 (...[1, 2, 3])  //
861              // p1 becomes 1, p2 becomes array [2, 3]
862
863
864
865
866.. index::
867   assignable type
868   Object
869   string
870   array
871
872|
873
874
875.. _Type Inference:
876
877Type Inference
878**************
879
880.. meta:
881    frontend_status: Done
882
883|LANG| supports strong typing but allows not to burden a programmer with the
884task of specifying type annotations everywhere. A smart compiler can infer
885types of some entities and expressions from the surrounding context.
886This technique called *type inference* allows keeping type safety and
887program code readability, doing less typing, and focusing on business logic.
888Type inference is applied by the compiler in the following contexts:
889
890- :ref:`Type Inference for Integer Constant Expressions`;
891- Variable and constant declarations (see :ref:`Type Inference from Initializer`);
892- Implicit generic instantiations (see :ref:`Implicit Generic Instantiations`);
893- Function, method or lambda return type (see :ref:`Return Type Inference`);
894- Lambda expression parameter type (see :ref:`Lambda Signature`);
895- Array literal type inference (see :ref:`Array Literal Type Inference from Context`,
896  and :ref:`Array Type Inference from Types of Elements`);
897- Object literal type inference (see :ref:`Object Literal`);
898- Smart types (see :ref:`Smart Types`).
899
900.. index::
901   strong typing
902   type annotation
903   smart compiler
904   type inference
905   entity
906   surrounding context
907   code readability
908   type safety
909   context
910   variable declaration
911   constant declaration
912   generic instantiation
913   function return type
914   function
915   method return type
916   method
917   return type
918   lambda expression
919   parameter type
920   array literal
921   Object literal
922   smart type
923
924|
925
926.. _Type Inference for Integer Constant Expressions:
927
928Type Inference for Integer Constant Expressions
929===============================================
930
931For :ref:`Constant Expressions` of integer types
932the type of expression is first evaluated from the expression
933in the following way:
934
935- For an integer literal the type is the default type of the literal:
936  ``int`` or ``long`` (see :ref:`Integer Literals`);
937
938- For a named constant the type is specified in the constant declaration;
939
940- For an operator the result type is evaluated accoriding rules of
941  this operator;
942
943- For :ref:`Cast expression` type is specified in the expression
944  target type.
945
946If the evaluated result type is of an integer type,
947it can be inferred to smaller integer *target type* from the context,
948if the following conditions are met:
949
950#. The top-level expression is not a cast expression;
951
952#. The value of the expression fits into the range of the *target type*.
953
954The examples below illustrate valid and invalid narrowing.
955
956.. code-block-meta:
957   expect-cte:
958
959.. code-block:: typescript
960   :linenos:
961
962    let b: byte = 127 // ok, int -> byte narrowing
963    b = 64 + 63 // ok, int -> byte narrowing
964    b = 128 // compile-time-error, value is out of range
965    b = 1.0 // compile-time-error, floating-point value cannot be narrowed
966    b = 1 as short // // compile-time-error, cast expresion
967
968    let s: short = 32768 // compile-time-error, value is out of range
969
970.. index::
971   narrowing
972   constant
973   constant expression
974   integer conversion
975   integer type
976   expression
977   conversion
978   type
979   value
980
981|
982
983.. _Smart Types:
984
985Smart Types
986===========
987
988.. meta:
989    frontend_status: Partly
990    todo: implement a dataflow check for loops and try-catch blocks
991
992Data entities like local variables (see :ref:`Variable and Constant Declarations`)
993and parameters (see :ref:`Parameter List`), if not captured in a lambda body and
994modified by the lambda code, are subjected to *smart typing*.
995
996Every data entity has a static type, which is specified explicitly or
997inferred at the point of declaration. This type defines the set of operations
998that can be applied to the entity (namely, what methods can be called, and what
999other entities can be accessed if the entity acts as a receiver of the
1000operation):
1001
1002.. code-block:: typescript
1003   :linenos:
1004
1005    let a = new Object
1006    a.toString() // entity 'a' has method toString()
1007
1008.. index::
1009   smart type
1010   data entity
1011   variable
1012   parameter
1013   class variable
1014   local variable
1015   smart typing
1016   lambda code
1017   function
1018   method
1019   static type
1020   inferred type
1021   receiver
1022   access
1023   declaration
1024
1025If an entity is class type (see :ref:`Classes`), interface type (see
1026:ref:`Interfaces`), or union type (see :ref:`Union Types`), then the compiler
1027can narrow (smart cast) a static type to a more precise type (smart type), and
1028allow operations that are specific to the type so narrowed:
1029
1030.. code-block:: typescript
1031   :linenos:
1032
1033    function boo() {
1034        let a: number | string = 42
1035        a++ /* Here we know for sure that type of 'a' is number and number-specific
1036           operations are type-safe */
1037    }
1038
1039    class Base {}
1040    class Derived extends Base { method () {} }
1041    function goo() {
1042       let b: Base = new Derived
1043       b.method () /* Here we know for sure that type of 'b' is Derived and Derived-specific
1044           operations can be applied in type-safe way */
1045    }
1046
1047Other examples are explicit calls to ``instanceof``
1048(see :ref:`InstanceOf Expression`) or checks against ``null``
1049(see :ref:`Reference Equality`) as part of ``if`` statements
1050(see :ref:`if Statements`) or conditional expressions
1051(see :ref:`Conditional Expressions`):
1052
1053.. code-block:: typescript
1054   :linenos:
1055
1056    function foo (b: Base, d: Derived|null) {
1057        if (b instanceof Derived) {
1058            b.method()
1059        }
1060        if (d != null) {
1061            d.method()
1062        }
1063    }
1064
1065.. index::
1066   type
1067   entity
1068   local variable
1069   interface type
1070   class type
1071   union type
1072   context
1073   compiler
1074   narrowing
1075   smart cast
1076   smart type
1077   if statement
1078   conditional expression
1079   entity
1080   class type
1081   static type
1082   narrowed type
1083   instanceof
1084   null
1085   semantic check
1086   reference equality
1087
1088In like cases, a smart compiler can deduce the smart type of an entity without
1089requiring unnecessary casting conversions (see :ref:`Cast Expression`).
1090
1091Overloading (see :ref:`Function, Method and Constructor Overloading`) can cause
1092tricky situations when a smart type leads to the call of a function or a method
1093(see :ref:`Overload Resolution`) that suits smart rather than static type of an
1094argument:
1095
1096.. code-block:: typescript
1097   :linenos:
1098
1099    function foo (p: Base) {}
1100    function foo (p: Derived) {}
1101
1102    function too() {
1103       let b: Base = new Derived
1104       foo (b) // potential ambiguity in case of smart type, foo(p:Base) is to be called
1105       foo (b as Derived) // no ambiguity,  foo(p:Derived) is to be called
1106    }
1107
1108Particular cases supported by the compiler are determined by the compiler
1109implementation.
1110
1111.. index::
1112   compiler
1113   smart type
1114   smart compiler
1115   entity
1116   casting conversion
1117   overloading
1118   conversion
1119   function
1120   method
1121   conversion overloading
1122   function overloading
1123   method overloading
1124   static type
1125   argument
1126   implementation
1127   compiler
1128
1129|
1130
1131.. _Overloading and Overriding:
1132
1133Overloading and Overriding
1134**************************
1135
1136Two important concepts apply to different contexts and entities throughout
1137this specification as follows:
1138
1139#. *Overloading* allows defining and using functions (in general sense,
1140   including methods and constructors) with the same name but different
1141   signatures. The actual function to be called is determined at compile
1142   time. Thus, *overloading* is related to compile-time polymorphism.
1143
1144#. *Overriding* is closely connected with inheritance. It is used on methods
1145   but not on functions. Overriding allows a subclass to offer a specific
1146   implementation of a method already defined in its parent class.
1147   The actual method to be called is determined at runtime based on object type.
1148   Thus, overriding is related to runtime polymorphism.
1149
1150|LANG| uses two semantic rules related to these concepts:
1151
1152-  *Overload-equivalence* rule: the *overloading* of two entities is
1153   correct if their signatures are **not** *overload-equivalent* (see
1154   :ref:`Overload-Equivalent Signatures`).
1155
1156-  *Override-compatibility* rule: the *overriding* of two entities is
1157   correct if their signatures are *override-compatible* (see
1158   :ref:`Override-Compatible Signatures`).
1159
1160See :ref:`Overloading for Functions`,
1161:ref:`Overloading and Overriding in Classes`, and
1162:ref:`Overloading and Overriding in Interfaces` for details.
1163
1164.. index::
1165   overloading
1166   overriding
1167   context
1168   entity
1169   function
1170   constructor
1171   method
1172   signature
1173   compile-time polymorphism
1174   subclass
1175   runtime polymorphism
1176   inheritance
1177   parent class
1178   object type
1179   runtime
1180   overload-equivalence
1181   override-compatibility
1182   overload-equivalent signature
1183   overriding
1184   overloading
1185
1186|
1187
1188.. _Overload-Equivalent Signatures:
1189
1190Overload-Equivalent Signatures
1191==============================
1192
1193.. meta:
1194    frontend_status: Partly
1195
1196Signatures *S1* with parameters *S1P*:sub:`1`, ... , *S1P*:sub:`n`, and *S2* with
1197the same number of parameters *S2P*:sub:`1`, ... , *S2P*:sub:`n`
1198are *overload-equivalent* if the *effective types* of parameters (see
1199:ref:`Type Erasure`) *S1P*:sub:`i` and *S2P*:sub:`i` for each *i* are
1200*overload-equavalent*.
1201
1202**Notes:**
1203
1204-  For an optional parameter (see :ref:`Optional Parameters`) in the form
1205   ``ident?: T``, the actual parameter type is considered, i.e., union type
1206   ``T | undefined``.
1207
1208-  Type parameter constraint ``Object|null|undefined`` (see
1209   :ref:`Type Parameter Constraint`) is condidered for a type parameter if
1210   no constraint is set explicitly.
1211
1212Parameters *S1P*:sub:`i` and *S2P*:sub:`i` are *overload-equavalent*, if
1213the are simultaneously ``rest`` or not ``rest`` parameters and if:
1214
1215#. Type of *S1P*:sub:`i` is a *type parameter* and type of *S2P*:sub:`i`
1216   is a subtype of *type parameter constraint* or a *type parameter*;
1217
1218#. Type of *S1P*:sub:`i` is *generic type*
1219   ``G`` <``T``:sub:`1`, ``...``, ``T``:sub:`n`>, where at least one
1220   ``T``:sub:`i` is a type parameter, and a
1221   type of *S2P*:sub:`i` is also ``G`` with any
1222   list of :ref:`Type Arguments` or a *union type* that contains ``G``;
1223
1224#. Types of *S1P*:sub:`i` and *S2P*:sub:`i` are
1225   *union types* containing types that fall into either provision above;
1226
1227#. Types of *S1P*:sub:`i` and *S2P*:sub:`i` are identical (see
1228   :ref:`Type Identity`).
1229
1230Parameter names and return types do not influence *overload equivalence*.
1231Signatures are *overload-equivalent*  in the following examples:
1232
1233.. index::
1234   overload-equivalent signature
1235   signature
1236   parameter
1237   type parameter
1238   parameter type
1239   non-generic reference type
1240   union type
1241   reference type
1242   generic type
1243   type argument
1244   overriding
1245   parameter name
1246   return type
1247   overload equivalence
1248   type identity
1249   overload equivalence
1250
1251.. code-block-meta:
1252
1253.. code-block:: typescript
1254   :linenos:
1255
1256   (x: number): void
1257   (y: number): void
1258
1259.. code-block-meta:
1260
1261.. code-block:: typescript
1262   :linenos:
1263
1264   (x: number): void
1265   (y: number): number
1266
1267.. code-block-meta:
1268
1269.. code-block:: typescript
1270   :linenos:
1271
1272   class G<T>
1273   (y: number): void
1274   (x: T): void
1275
1276.. code-block-meta:
1277
1278.. code-block:: typescript
1279   :linenos:
1280
1281   class G<T>
1282   (y: G<number>): void
1283   (x: G<T>): void
1284
1285
1286.. code-block-meta:
1287
1288.. code-block:: typescript
1289   :linenos:
1290
1291   class G<T, S>
1292   (y: T): void
1293   (x: S): void
1294
1295
1296Signatures are not *overload-equivalent* in the following examples:
1297
1298.. index::
1299   overload-equivalent signature
1300
1301.. code-block-meta:
1302
1303.. code-block:: typescript
1304   :linenos:
1305
1306   (x: number): void
1307   (y: string): void
1308
1309.. code-block-meta:
1310
1311.. code-block:: typescript
1312   :linenos:
1313
1314   class A { /*body*/}
1315   class B extends A { /*body*/}
1316   (x: A): void
1317   (y: B): void
1318
1319.. code-block-meta:
1320
1321.. code-block:: typescript
1322   :linenos:
1323
1324   class A<T> {
1325   (p: T)
1326   (p: T[])
1327
1328.. code-block-meta:
1329
1330.. code-block:: typescript
1331   :linenos:
1332
1333   class Base {}
1334   class Derived1 extends Base {}
1335   class Derived2 extends Base {}
1336   (p: Derived1 | Derived2 ): void
1337   (p: Base): void
1338
1339.. code-block-meta:
1340
1341.. code-block:: typescript
1342   :linenos:
1343
1344   class G<T>
1345   (x: G<number>): void
1346   (y: G<string>): void
1347
1348.. code-block-meta:
1349
1350.. code-block:: typescript
1351   :linenos:
1352
1353   class G<T extends number>
1354   (x: T): void
1355   (y: string): void
1356
1357|
1358
1359.. _Override-Compatible Signatures:
1360
1361Override-Compatible Signatures
1362==============================
1363
1364.. meta:
1365    frontend_status: Partly
1366
1367If there are two classes ``Base`` and ``Derived``, and class ``Derived``
1368overrides the method ``foo()`` of ``Base``, then ``foo()`` in ``Base`` has
1369signature ``S``:sub:`1` <``V``:sub:`1` ``, ... V``:sub:`k`>
1370(``U``:sub:`1` ``, ..., U``:sub:`n`) ``:U``:sub:`n+1`, and ``foo()`` in
1371``Derived`` has signature ``S``:sub:`2` <``W``:sub:`1` ``, ... W``:sub:`l`>
1372(``T``:sub:`1` ``, ..., T``:sub:`m`) ``:T``:sub:`m+1` as in the example below:
1373
1374.. index::
1375   override-compatible signature
1376   class
1377   base class
1378   derived class
1379   signature
1380
1381.. code-block:: typescript
1382   :linenos:
1383
1384    class Base {
1385       foo <V1, ... Vk> (p1: U1, ... pn: Un): Un+1
1386    }
1387    class Derived extends Base {
1388       override foo <W1, ... Wl> (p1: T1, ... pm: Tm): Tm+1
1389    }
1390
1391The signature ``S``:sub:`2` is override-compatible with ``S``:sub:`1` only
1392if **all** of the following conditions are met:
1393
13941. Number of parameters of both methods is the same, i.e., ``n = m``.
13952. Each parameter type ``T``:sub:`i` is a supertype of ``U``:sub:`i`
1396   for ``i`` in ``1..n`` (contravariance).
13973. If return type ``T``:sub:`m+1` is ``this``, then ``U``:sub:`n+1` is ``this``,
1398   or any of superinterfaces or superclass of the current type. Otherwise,
1399   return type ``T``:sub:`m+1` is a subtype of ``U``:sub:`n+1` (covariance).
14004. Number of type parameters of either method is the same, i.e., ``k = l``.
14015. Constraints of ``W``:sub:`1`, ... ``W``:sub:`l` are to be contravariant
1402   (see :ref:`Invariance, Covariance and Contravariance`) to the appropriate
1403   constraints of ``V``:sub:`1`, ... ``V``:sub:`k`.
1404
1405.. index::
1406   signature
1407   override-compatible signature
1408   override compatibility
1409   class
1410   signature
1411   method
1412   parameter
1413   type
1414   contravariant
1415   covariance
1416   invariance
1417   constraint
1418   type parameter
1419
1420The following rule applies to generics:
1421
1422   - Derived class must have type parameter constraints to be subtype
1423     (see :ref:`Subtyping`) of the respective type parameter
1424     constraint in the base type;
1425   - Otherwise, a :index:`compile-time error` occurs.
1426
1427.. index::
1428   generic
1429   derived class
1430   subtyping
1431   subtype
1432   type parameter
1433   base type
1434
1435.. code-block:: typescript
1436   :linenos:
1437
1438   class Base {}
1439   class Derived extends Base {}
1440   class A1 <CovariantTypeParameter extends Base> {}
1441   class B1 <CovariantTypeParameter extends Derived> extends A1<CovariantTypeParameter> {}
1442       // OK, derived class may have type compatible constraint of type parameters
1443
1444   class A2 <ContravariantTypeParameter extends Derived> {}
1445   class B2 <ContravariantTypeParameter extends Base> extends A2<ContravariantTypeParameter> {}
1446       // Compile-time error, derived class cannot have non-compatible constraints of type parameters
1447
1448The semantics is illustrated by the examples below:
1449
14501. **Class/Interface Types**
1451
1452.. code-block:: typescript
1453    :linenos:
1454
1455    interface Base {
1456        param(p: Derived): void
1457        ret(): Base
1458    }
1459
1460    interface Derived extends Base {
1461        param(p: Base): void    // Contravariant parameter
1462        ret(): Derived          // Covariant return type
1463    }
1464
1465.. index::
1466   class type
1467   interface type
1468   contravariant parameter
1469   covariant return type
1470
14712. **Function Types**
1472
1473.. code-block:: typescript
1474    :linenos:
1475
1476    interface Base {
1477        param(p: (q: Base)=>Derived): void
1478        ret(): (q: Derived)=> Base
1479    }
1480
1481    interface Derived extends Base {
1482        param(p: (q: Derived)=>Base): void  // Covariant parameter type, contravariant return type
1483        ret(): (q: Base)=> Derived          // Contravariant parameter type, covariant return type
1484    }
1485
1486.. index::
1487   function type
1488   covariant parameter type
1489   contravariant return type
1490   contravariant parameter type
1491   covariant return type
1492
14933. **Union Types**
1494
1495.. code-block:: typescript
1496   :linenos:
1497
1498    interface BaseSuperType {}
1499    interface Base extends BaseSuperType {
1500       // Overriding for parameters
1501       param<T extends Derived, U extends Base>(p: T | U): void
1502
1503       // Overriding for return type
1504       ret<T extends Derived, U extends Base>(): T | U
1505    }
1506
1507    interface Derived extends Base {
1508       // Overriding kinds for parameters, Derived <: Base
1509       param<T extends Base, U extends Object>(
1510          p: Base | BaseSuperType // contravariant parameter type:  Derived | Base <: Base | BaseSuperType
1511       ): void
1512       // Overriding kinds for return type
1513       ret<T extends Base, U extends BaseSuperType>(): T | U
1514    }
1515
1516.. index::
1517   union type
1518   return type
1519
15204. **Type Parameter Constraint**
1521
1522.. code-block:: typescript
1523    :linenos:
1524
1525    interface Base {
1526        param<T extends Derived>(p: T): void
1527        ret<T extends Derived>(): T
1528    }
1529
1530    interface Derived extends Base {
1531        param<T extends Base>(p: T): void       // Contravariance for constraints of type parameters
1532        ret<T extends Base>(): T                // Contravariance for constraints of the return type
1533    }
1534
1535
1536The example below illustrates override compatibility with ``Object``:
1537
1538.. index::
1539   contravariance
1540   constraint
1541   return type
1542   type parameter
1543   override compatibility
1544
1545.. code-block:: typescript
1546   :linenos:
1547
1548    interface Base {
1549       kinds_of_parameters<T extends Derived, U extends Base>( // It represents all possible kinds of parameter type
1550          p01: Derived,
1551          p02: (q: Base)=>Derived,
1552          p03: number,
1553          p04: Number,
1554          p05: T | U,
1555          p06: E1,
1556          p07: Base[],
1557          p08: [Base, Base]
1558       ): void
1559       kinds_of_return_type(): Object // It can be overridden by all subtypes except primitive ones
1560    }
1561    interface Derived extends Base {
1562       kinds_of_parameters( // Object is a supertype for all types except primitive ones
1563          p1: Object,
1564          p2: Object,
1565          p3: Object, // Compile-time error: number and Object are not override-compatible
1566          p4: Object,
1567          p5: Object,
1568          p6: Object,
1569          p7: Object,
1570          p8: Object
1571       ): void
1572    }
1573
1574    interface Derived1 extends Base {
1575       kinds_of_return_type(): Base // Valid overriding
1576    }
1577    interface Derived2 extends Base {
1578       kinds_of_return_type(): (q: Derived)=> Base // Valid overriding
1579    }
1580    interface Derived3 extends Base {
1581       kinds_of_return_type(): number // Valid overriding
1582    }
1583    interface Derived4 extends Base {
1584       kinds_of_return_type(): number | string // Valid overriding
1585    }
1586    interface Derived5 extends Base {
1587       kinds_of_return_type(): E1 // Valid overriding
1588    }
1589    interface Derived6 extends Base {
1590       kinds_of_return_type(): Base[] // Valid overriding
1591    }
1592    interface Derived7 extends Base {
1593       kinds_of_return_type(): [Base, Base] // Valid overriding
1594    }
1595
1596.. index::
1597   parameter type
1598   overriding
1599   subtype
1600   supertype
1601   overriding
1602   compatibility
1603
1604|
1605
1606.. _Overloading for Functions:
1607
1608Overloading for Functions
1609=========================
1610
1611.. meta:
1612    frontend_status: Partly
1613
1614*Overloading* must only be considered for functions because inheritance for
1615functions is not defined.
1616
1617The correctness check for functions overloading is performed if two or more
1618functions with the same name are accessible (see :ref:`Accessible`) in a scope
1619(see :ref:`Scopes`).
1620
1621A function can be declared in, or imported to a scope.
1622
1623The semantic check for overloading functions is as follows:
1624
1625-  If function signatures are *overload-equivalent*, then
1626   a :index:`compile-time error` occurs.
1627
1628-  Otherwise, *overloading* is valid.
1629
1630It is discussed in detail in :ref:`Function Overloading` and
1631:ref:`Import and Overloading of Function Names`.
1632
1633.. index::
1634   overloading
1635   function
1636   inheritance
1637   correctness check
1638   semantic check
1639   accessibility
1640   access
1641   scope
1642   import
1643   compilation unit
1644   overload-equivalent signature
1645
1646|
1647
1648.. _Overloading and Overriding in Classes:
1649
1650Overloading and Overriding in Classes
1651=====================================
1652
1653.. meta:
1654    frontend_status: Partly
1655
1656Both *overloading* and *overriding* must be considered in case of classes for
1657methods and partly for constructors.
1658
1659**Note**. Only accessible (see :ref:`Accessible`) methods are subjected to
1660overloading and overriding. The same rules also apply to accessors in case of
1661overriding.
1662
1663An overriding member can keep or extend an access modifier (see
1664:ref:`Access Modifiers`) of a member that is inherited or implemented.
1665Otherwise, a :index:`compile-time error` occurs.
1666
1667An attempt to override a private method of a superclass, or to declare a method
1668with the same name as the private method with default implementation from any
1669superinterface causes a :index:`compile-time error`.
1670
1671.. index::
1672   overloading
1673   inheritance
1674   overriding
1675   class
1676   constructor
1677   accessibility
1678   access
1679   private method
1680   method
1681   subclass
1682   accessor
1683   superclass
1684   access modifier
1685   implementation
1686   superinterface
1687
1688.. code-block:: typescript
1689   :linenos:
1690
1691   class Base {
1692      public public_member() {}
1693      protected protected_member() {}
1694      internal internal_member() {}
1695      private private_member() {}
1696   }
1697
1698   interface Interface {
1699      public_member()             // All members are public in interfaces
1700      private private_member() {} // Except private methods with default implementation
1701   }
1702
1703   class Derived extends Base implements Interface {
1704      public override public_member() {}
1705         // Public member can be overridden and/or implemented by the public one
1706      public override protected_member() {}
1707         // Protected member can be overridden by the protected or public one
1708      internal internal_member() {}
1709         // Internal member can be overridden by the internal one only
1710      override private_member() {}
1711         // A compile-time error occurs if an attempt is made to override private member
1712         // or implement the private methods with default implementation
1713   }
1714
1715The table below represents semantic rules that apply in various contexts:
1716
1717.. list-table::
1718   :width: 100%
1719   :widths: 50 50
1720   :header-rows: 1
1721
1722   * - Context
1723     - Semantic Check
1724   * - Two *instance methods*, two *static methods* with the same name, or two
1725       *constructors* are defined in the same class.
1726     - If signatures are *overload-equivalent*, (see :ref:`Overload-Equivalent
1727       Signatures`), then a :index:`compile-time error` occurs. Otherwise,
1728       *overloading* is used.
1729
1730
1731.. index::
1732   semantic check
1733   instance method
1734   method
1735   static method
1736   constructor
1737   overload equivalence
1738   overloading
1739   overload-equivalent signature
1740   overriding
1741   implementation
1742   public
1743   internal
1744   private
1745
1746.. code-block:: typescript
1747   :linenos:
1748
1749   class aClass {
1750
1751      instance_method_1() {}
1752      instance_method_1() {} // compile-time error: instance method duplication
1753
1754      static static_method_1() {}
1755      static static_method_1() {} // compile-time error: static method duplication
1756
1757      instance_method_2() {}
1758      instance_method_2(p: number) {} // valid overloading
1759
1760      static static_method_2() {}
1761      static static_method_2(p: string) {} // valid overloading
1762
1763      constructor() {}
1764      constructor() {} // compile-time error: constructor duplication
1765
1766      constructor(p: number) {}
1767      constructor(p: string) {} // valid overloading
1768
1769   }
1770
1771.. list-table::
1772   :width: 100%
1773   :widths: 50 50
1774   :header-rows: 0
1775
1776   * - An *instance method* is defined in a subclass with the same name as the
1777       *instance method* in a superclass.
1778     - If signatures are *override-compatible* (see
1779       :ref:`Override-Compatible Signatures`), then *overriding* is used.
1780       Otherwise, *overloading* is used.
1781
1782
1783.. code-block:: typescript
1784   :linenos:
1785
1786   class Base {
1787      method_1() {}
1788      method_2(p: number) {}
1789   }
1790   class Derived extends Base {
1791      override method_1() {} // overriding
1792      method_2(p: string) {} // overloading
1793   }
1794
1795.. list-table::
1796   :width: 100%
1797   :widths: 50 50
1798   :header-rows: 0
1799
1800   * - A *static method* is defined in a subclass with the same name as the
1801       *static method* in a superclass.
1802     - If signatures are *overload-equivalent* (see
1803       :ref:`Overload-Equivalent Signatures`), then the static method in the
1804       subclass *hides* the previous static method.Otherwise, *overloading* is
1805       used.
1806
1807.. index::
1808   instance method
1809   static method
1810   subclass
1811   superclass
1812   override-compatible signature
1813   override-compatibility
1814   overloading
1815   hiding
1816   overriding
1817
1818.. code-block:: typescript
1819   :linenos:
1820
1821   class Base {
1822      static method_1() {}
1823      static method_2(p: number) {}
1824   }
1825   class Derived extends Base {
1826      static method_1() {} // hiding
1827      static method_2(p: string) {} // overloading
1828   }
1829
1830.. list-table::
1831   :width: 100%
1832   :widths: 50 50
1833   :header-rows: 0
1834
1835   * - A *constructor* is defined in a subclass.
1836     - All base class constructors are available for call in all derived class
1837       constructors.
1838
1839
1840.. code-block:: typescript
1841   :linenos:
1842
1843   class Base {
1844      constructor() {}
1845      constructor(p: number) {}
1846   }
1847   class Derived extends Base {
1848      constructor(p: string) {
1849           super()
1850           super(5)
1851      }
1852   }
1853
1854.. index::
1855   constructor
1856   subclass
1857   class constructor
1858   derived class constructor
1859
1860|
1861
1862.. _Overloading and Overriding in Interfaces:
1863
1864Overloading and Overriding in Interfaces
1865========================================
1866
1867.. meta:
1868    frontend_status: Done
1869
1870.. list-table::
1871   :width: 100%
1872   :widths: 50 50
1873   :header-rows: 1
1874
1875   * - Context
1876     - Semantic Check
1877   * - A method is defined in a subinterface with the same name as the method
1878       in the superinterface.
1879     - If signatures are *override-compatible* (see
1880       :ref:`Override-Compatible Signatures`), then *overriding* is used.
1881       Otherwise, *overloading* is used.
1882
1883.. code-block:: typescript
1884   :linenos:
1885
1886   interface Base {
1887      method_1()
1888      method_2(p: number)
1889   }
1890   interface Derived extends Base {
1891      method_1() // overriding
1892      method_2(p: string) // overloading
1893   }
1894
1895
1896.. list-table::
1897   :width: 100%
1898   :widths: 50 50
1899   :header-rows: 0
1900
1901   * - Two methods with the same name are defined in the same interface.
1902     - *Overloading* is used. A :index:`compile-time error` occurs if signatures
1903       are *overload-equivalent*.
1904
1905
1906.. index::
1907   method
1908   subinterface
1909   superinterface
1910   semantic check
1911   override-compatible
1912   overload-equivalent
1913   interface
1914   overloading
1915
1916.. code-block:: typescript
1917   :linenos:
1918
1919   interface anInterface {
1920      instance_method_1()
1921      instance_method_1()  // Compile-time error: instance method duplication
1922
1923      instance_method_2()
1924      instance_method_2(p: number)  // Valid overloading
1925   }
1926
1927|
1928
1929.. _Overload Resolution:
1930
1931Overload Resolution
1932*******************
1933
1934.. meta:
1935    frontend_status: Done
1936
1937*Overload resolution* is used to select one entity to call from a set of
1938*potentially applicable candidates* in a function, method, or constructor call.
1939Overload resolution is performed in two steps as follows:
1940
1941#. Select *applicable candidates* from *potentially applicable candidates*;
1942
1943#. If there is more than one *applicable candidate*, then select the *best
1944   candidate*.
1945
1946**Note**. The first step is performed in all cases, even if there is
1947only one *applicable candidate* to check *call signature compatibility*.
1948
1949.. index::
1950   overload resolution
1951   entity
1952   applicable candidate
1953   call signature compatibility
1954   constructor call
1955   constructor
1956   potentially applicable candidate
1957   best candidate
1958
1959|
1960
1961.. _Selection of Applicable Candidates:
1962
1963Selection of Applicable Candidates
1964==================================
1965
1966.. meta:
1967    frontend_status: Partly
1968    todo: adapt the implementation to the latest specification (handle rest, union, functional types properly)
1969    todo: make the ISA/assembler/runtime handle union types without collision - eg foo(arg: A|B) and foo(arg: C|D)
1970
1971The selection of *applicable candidates* is the process of checking
1972:ref:`Compatibility of Call Arguments` for all entities from the set of
1973*potentially applicable candidates*. If any argument is not compatible with
1974the corresponding parameter type, then the entity is deleted from the set.
1975
1976**Note**. Compile-time errors are not reported at this stage.
1977
1978After processing all entities, one of the following results is achieved:
1979
1980- Set is empty (all entities are deleted). A compile-time error occurs,
1981  and the *overload resolution* is completed.
1982
1983- Only one entity is left in the set. This is the entity to call, and
1984  the *overload resolution* is completed.
1985
1986- More than one entity is left in the set. The next step of the
1987  *overload resolution* is to be performed.
1988
1989.. index::
1990   applicable candidate
1991   potentially applicable candidate
1992   semantic check
1993   compatibility
1994   call argument
1995   entity
1996   parameter type
1997   overload resolution
1998   overloaded function
1999   call
2000
2001Two overloaded functions are considered in the following example:
2002
2003.. code-block:: typescript
2004   :linenos:
2005
2006   class Base { }
2007   class Derived extends Base { }
2008
2009   function foo(p: Base) { ... }     // #1
2010   function foo(p: Derived) { ... }  // #2
2011
2012   foo(new Derived) // two applicable candidates for this call
2013                    // next step of overload resolution is required
2014
2015   foo(new Base)    // one applicable candidate
2016                    // overload resolution is completed
2017                    // #1 will be called
2018
2019   foo(new Base, 5) // no candidates, compile-time error
2020
2021|
2022
2023.. _Selection of Best Candidate:
2024
2025Selection of Best Candidate
2026===========================
2027
2028.. meta:
2029    frontend_status: Partly
2030
2031If the set of *applicable candidates* has two or more candidates, then the
2032best candidate for the given list of arguments is to be identified, if possible.
2033
2034The selection of the best candidate is based on the following:
2035
2036- There are no candidates with the same list of parameters, as this situation
2037  is already forbidden by the compiler (at the place of declaration or import)
2038  (see :ref:`Overload-Equivalent Signatures`);
2039
2040- If several candidates can be called correctly by using the same argument list,
2041  then at least one implicit argument transformation   must be applied to make
2042  the call.
2043
2044Possible argument transformations are listed below:
2045
2046- Passing default values to fill any missing arguments
2047  (:ref:`Optional Parameters`);
2048
2049- Passing the empty array to replace a ``rest`` parameter that has no argument;
2050
2051- Folding several arguments to the array for a ``rest`` parameter.
2052
2053.. index::
2054   applicable candidate
2055   best candidate
2056   parameter
2057   compiler
2058   import site
2059   argument transformation
2060   value
2061   overload-equivalent signature
2062   rest parameter
2063   conversion
2064   array
2065   rest parameter
2066
2067The examples of transformations are presented below:
2068
2069.. code-block:: typescript
2070   :linenos:
2071
2072   function foo1(x?: string) {}
2073   foo1() // passing default value -> foo(undefined)
2074
2075   function foo2(...x: int[]) {}
2076   foo2() // passing empty array -> foo([])
2077   foo2(1, 2) // folding to array -> foo(...[1, 2])
2078
2079The *best candidate* is the candidate that requires no transformation for all
2080arguments. If there is such a single candidate, then other candidates are not
2081considered. Such *best candidate* is represented
2082in the example below:
2083
2084.. code-block:: typescript
2085   :linenos:
2086
2087   function max(a: number, b: number)  // #1
2088   function max(...args: number[]) // #2
2089
2090   max(1, 2) // #1 - is the best candidate, no transformation
2091
2092.. index::
2093   best candidate
2094   transformation
2095   argument
2096
2097If there is no *best candidate* at this step, then each candidate
2098is compared to other candidates.
2099The following sequence of checks is used to calculate a partially *better*
2100relation based on the comparison of candidates *C1* and *C2*:
2101
2102
2103**Check 1**. If *C1* has fewer parameters, i.e., default values or an empty
2104``rest`` argument are used instead of the absent arguments in the *C2* call,
2105then *C1* is *better*.
2106
2107.. code-block:: typescript
2108   :linenos:
2109
2110   function foo(n: number, s?: string)  // #1
2111   function foo(n: number)              // #2
2112
2113   foo(1) // #2 is better, less parameters
2114
2115   function bar(...args: number[])  // #1
2116   function bar()                   // #2
2117
2118   bar() // #2 is better, less parameters
2119
2120   function goo(...args: number[])  // #1
2121   function goo(n?: number)         // #2
2122
2123   goo() // none is better
2124
2125.. index::
2126   best candidate
2127   better candidate
2128   partially better candidate
2129   rest argument
2130
2131**Check 2**. If *C1* has a non-``rest`` parameter(s) for a non-empty list of
2132arguments, and *C2* has a ``rest`` parameter, then *C1* is *better*.
2133
2134.. code-block:: typescript
2135   :linenos:
2136
2137   function foo(sum: number, a: number, b: number)  // #1
2138   function foo(sum: number, ...x: number[])        // #2
2139
2140   foo(1, 2, 3) // #1 is better, non-rest parameters
2141
2142.. index::
2143   argument
2144   better candidate
2145   rest argument
2146
2147**Check 3**. If an argument type is a subtype of parameter type for *C1* and
2148not for *C2*, then *C1* is *better* for this argument.
2149
2150.. code-block:: typescript
2151   :linenos:
2152
2153   function foo(n: int)  // #1
2154   function foo(n: long) // #2
2155
2156   foo(1) // #1 is better, argument type is subtype of parameter type
2157   foo(1 as long) // #2 is better
2158
2159.. index::
2160   argument
2161   better candidate
2162   argument transformation
2163
2164**Check 4**. If an argument type is a subtype of parameter type for both *C1*
2165and *C2*, but type of *C1* is identical for the argument type and type of *C2*
2166is not, then *C1* is *better* for this argument.
2167
2168.. code-block:: typescript
2169   :linenos:
2170
2171    class C {}
2172    class D extends C {}
2173
2174    function foo(x: C) {} // #1
2175    function foo(x: D) {} // #2
2176
2177    foo(new C) // #1 is better
2178
2179**Check 5**. Otherwise, none is better for this argument, including cases:
2180
2181-  An argument type is a subtype of parameter type for both *C1*
2182   and *C2*, but neither is identical;
2183
2184-  An argument type is not a subtype for both *C1* and *C2*.
2185
2186.. code-block:: typescript
2187   :linenos:
2188
2189   function foo(x: number | boolean) // #1
2190   function foo(x: number | string)  // #2
2191
2192   foo(1.) // both subtype, none identical: none is better
2193
2194   function negate(x: long) // #1
2195   function negate(x: double) // #2
2196
2197   negate(1) // none subtype: none is better
2198
2199.. index::
2200   best candidate
2201   better candidate
2202   argument transformation
2203   numeric type
2204   conversion
2205   parameter
2206
2207A :index:`compile-time error` occurs if
2208*C1* is *better* for one argument, and *C2* is *better* for another argument
2209as represented in the example below:
2210
2211.. code-block:: typescript
2212   :linenos:
2213
2214   function goo(a: int; b: int | string)  // #1
2215   function goo(a: int | string, b: int)  // #2
2216
2217   goo(1, 1) // compile-time error, as
2218             // #1 is better for 1st argument,
2219             // #2 is better for 2nd argument.
2220
2221.. index::
2222   best candidate
2223   argument
2224   better candidate
2225
2226
2227If exactly one candidate is *better* than others,
2228then it is the *best candidate*.
2229Otherwise, if no single candidate is *better*,
2230:index:`compile-time error` occurs.
2231
2232|
2233
2234.. _Type Erasure:
2235
2236Type Erasure
2237*************
2238
2239*Type erasure* is the concept that denotes a special handling of some language
2240*types*, primarily :ref:`Generics`, in the semantics of the following language
2241operations that require the type to be preserved for execution:
2242
2243-  :ref:`InstanceOf Expression`;
2244-  :ref:`Cast Expression`;
2245-  :ref:`Overload-Equivalent Signatures`.
2246
2247In these operations some *types* are handled as their corresponding *effective
2248types*, while the *effective type* is defined as type mapping. The *effective
2249type* of a specific type ``T`` is always a supertype of ``T``. As a result,
2250two kinds of relationship are possible between an original type and an
2251*effective type*:
2252
2253-  *Effective type* of ``T`` is identical to ``T``, and *type erasure* has no
2254   effect.
2255
2256-  If *effective type* of ``T`` is not identical to ``T``, then the type ``T``
2257   is considered affected by *type erasure*, i.e., *erased*.
2258
2259.. index::
2260   type erasure
2261   instanceof expression
2262   cast expression
2263   overload-equivalent signature
2264   operation
2265   type
2266   effective type
2267   type mapping
2268   supertype
2269
2270In addition, accessing a value of type ``T``, including by
2271:ref:`Field Access Expression`, :ref:`Method Call Expression`, or
2272:ref:`Function Call Expression` can cause ``ClassCastError`` thrown if
2273type ``T``and the ``target`` type are both affected by *type erasure*, and the
2274value is produced by :ref:`Cast Expression`.
2275
2276.. code-block:: typescript
2277   :linenos:
2278
2279    class A<T> {
2280      field?: T
2281
2282      test(value: Object) {
2283        return value instanceof T  // CTE, T is erased
2284      }
2285
2286      cast(value: Object) {
2287        return value as T          // OK, but check is postponed
2288      }
2289    }
2290
2291    function castToA(p: Object) {
2292      p instanceof A<number> // CTE, A<number> is erased
2293
2294      return p as A<number>  // OK, but check is performed against A
2295    }
2296
2297.. index::
2298   type erasure
2299   field access
2300   method call
2301   target type
2302   cast expression
2303
2304Type mapping determines the *effective types* as follows:
2305
2306-  :ref:`Type Parameter Constraint` for :ref:`Type Parameters`.
2307
2308-  Instantiation of the same generic type (see
2309   :ref:`Explicit Generic Instantiations`) for *generic types* (see
2310   :ref:`Generics`), with its type arguments selected in accordance with
2311   :ref:`Type Parameter Variance` as outlined below:
2312
2313   - *Covariant* type parameters are instantiated with the constraint type;
2314
2315   - *Contravariant* type parameters are instantiated with the type ``never``;
2316
2317   - *Invariant* type parameters have no corresponding type argument, **TBD**
2318
2319-  Union type constructed from the effective types of types ``T1 | T2 ... Tn``
2320   within the original union type for :ref:`Union Types` in the form
2321   ``T1 | T2 ... Tn``.
2322
2323-  Same for :ref:`Array Types` in the form ``T[]`` as for generic type ``Array<T>``.
2324
2325-  Instantiation of ``FixedArray`` for ``FixedArray<T>`` instantiations, with
2326   the effective type of type argument ``T`` preserved.
2327
2328-  Instantiation of an internal generic function type with respect to
2329   the number of parameter types *n* for :ref:`Function Types` in the form
2330   ``(P1, P2 ..., Pn) => R``. Parameter types ``P1, P2 ... Pn`` are
2331   instantiated with ``object | null | undefined``, and the return type ``R``
2332   is instantiated with type ``never``.
2333
2334-  Instantiation of an internal generic tuple type with respect to
2335   the number of element types *n* for :ref:`Tuple Types` in the form
2336   ``[T1, T2 ..., Tn]``. **TBD**
2337
2338-  String for *string literal types* (see :ref:`Literal Types`).
2339
2340-  Enumeration base type of the same const enum type for *const enum* types
2341   (see :ref:`Enumerations`).
2342
2343-  Otherwise, the original type is preserved.
2344
2345.. index::
2346   type erasure
2347   type mapping
2348   generic type
2349   effective type
2350   instantiation
2351   type argument
2352   covariant type parameter
2353   type parameter
2354   contravariant type parameter
2355   invariant type parameter
2356   parameter type
2357   type argument
2358   type preservation
2359
2360|
2361
2362.. _Static Initialization:
2363
2364Static Initialization
2365*********************
2366
2367*Static initialization* is a routine performed once for each class
2368(see :ref:`Classes`), namespace (see :ref:`Namespace Declarations`),
2369separate module (see :ref:`Separate Modules`) or package module (see :ref:`Packages`).
2370
2371*Static initialization* execution involves execution of:
2372
2373- *Initializers* of *variables* or *static fields*
2374
2375- *Top-level statements*
2376
2377- Code inside *Static block*
2378
2379
2380*Static initialization* is performed before one of the following operations is first excecuted:
2381
2382- a static method or function of entity's scope is invoked
2383
2384- a static field or variable of entity's scope is accessed
2385
2386- entity, which is an interface or class, is instantiated
2387
2388- entity is a class, and its direct subclass is *statically initialized*
2389
2390Note: Any of the enlisted operations does not invoke *static initialization*
2391recursively if the *static initializaton* of the same entity is not complete.
2392
2393If *static initialization* routine execution is terminated due to the
2394exception thrown, then the initialization is not complete,
2395and any attempt to execute its *static initialization* once again will
2396produce an exception.
2397
2398For the concurrent execution (see :ref:`Coroutines (Experimental)`)
2399*static initialization* routine invokation involves synchronization
2400between all *coroutines* that try to invoke it to ensure that
2401initialization is performed only once and the operations
2402that require *static initialization* to be performed are executed after
2403the initialization completes.
2404
2405If *static initialization* routines of two concurrently initialized classes
2406has a circular dependence, it may lead to deadlock.
2407
2408|
2409
2410.. _Static Initialization Safety:
2411
2412Static Initialization Safety
2413============================
2414
2415If a *named reference* refers to a not yet initialized *entity*, including
2416
2417- variable (see :ref:`Variable and Constant Declarations`) of a separate module
2418  package (see :ref:`Packages`), or namespace (see :ref:`Namespace Declarations`)
2419
2420- a static field of the class (see :ref:`Static Fields`)
2421
2422then a compile-time error is produced.
2423
2424If it is not possible to detect an access to a not yet initalized *entity*,
2425then the runtime evaluation is performed as follows:
2426
2427- If type of the entity has a default value, then a default value is produced
2428
2429- Otherwise, ``NullPointerError`` is thrown
2430
2431
2432.. _Dispatch:
2433
2434Dispatch
2435********
2436
2437.. meta:
2438    frontend_status: Done
2439
2440As a result of assignment (see :ref:`Assignment`) to a variable or call (see
2441:ref:`Method Call Expression` or :ref:`Function Call Expression`), the actual
2442runtime type of a parameter of class or interface can become different from the
2443type explicitly specified or inferred at the point of declaration.
2444
2445In this situation method calls are dispatched during program execution based on
2446their actual type.
2447
2448This mechanism is called *dynamic dispatch*. Dynamic dispatch is used in
2449OOP languages to provide greater flexibility and the required level of
2450abstraction. Unlike *static dispatch* where the particular method to be called
2451is known at compile time, *dynamic dispatch* requires additional action during
2452program code execution. Compilation tools can optimize dynamic to static dispatch.
2453
2454.. index::
2455   dispatch
2456   assignment
2457   variable
2458   call
2459   method call expression
2460   method
2461   method call
2462   function call
2463   function
2464   runtime
2465   runtime type
2466   parameter
2467   class
2468   specified type
2469   inferred type
2470   point of declaration
2471   dynamic dispatch
2472   OOP (object-oriented programming)
2473   static dispatch
2474   compile time
2475
2476|
2477
2478.. _Compatibility Features:
2479
2480Compatibility Features
2481**********************
2482
2483Some features are added to |LANG| in order to support smooth |TS| compatibility.
2484Using these features while doing the |LANG| programming is not recommended in
2485most cases.
2486
2487.. index::
2488   compatibility
2489
2490|
2491
2492.. _Extended Conditional Expressions:
2493
2494Extended Conditional Expressions
2495================================
2496
2497.. meta:
2498    frontend_status: Done
2499
2500|LANG| provides extended semantics for conditional expressions
2501to ensure better |TS| alignment. It affects the semantics of the following:
2502
2503-  Conditional expressions (see :ref:`Conditional Expressions`,
2504   :ref:`Conditional-And Expression`, :ref:`Conditional-Or Expression`, and
2505   :ref:`Logical Complement`);
2506
2507-  ``while`` and ``do`` statements (see :ref:`While Statements and Do Statements`);
2508
2509-  ``for`` statements (see :ref:`For Statements`);
2510
2511-  ``if`` statements (see :ref:`if Statements`).
2512
2513**Note**. The extended semantics is to be deprecated in one of the future
2514versions of |LANG|.
2515
2516The extended semantics approach is based on the concept of *truthiness* that
2517extends the boolean logic to operands of non-boolean types.
2518
2519Depending on the kind of a valid expression's type, the value of the valid
2520expression can be handled as ``true`` or ``false`` as described in the table
2521below:
2522
2523.. index::
2524   extended conditional expression
2525   conditional expression
2526   alignment
2527   semantics
2528   conditional-and expression
2529   conditional-or expression
2530   while statement
2531   do statement
2532   for statement
2533   if statement
2534   truthiness
2535   non-boolean type
2536   expression type
2537
2538
2539.. list-table::
2540   :width: 100%
2541   :widths: 25 25 25 25
2542   :header-rows: 1
2543
2544   * - Value Type Kind
2545     - When ``false``
2546     - When ``true``
2547     - |LANG| Code Example to Check
2548   * - ``string``
2549     - empty string
2550     - non-empty string
2551     - ``s.length == 0``
2552   * - ``boolean``
2553     - ``false``
2554     - ``true``
2555     - ``x``
2556   * - ``enum``
2557     - ``enum`` constant handled as ``false``
2558     - ``enum`` constant handled as ``true``
2559     - ``x.valueOf()``
2560   * - ``number`` (``double``/``float``)
2561     - ``0`` or ``NaN``
2562     - any other number
2563     - ``n != 0 && !isNaN(n)``
2564   * - any integer type
2565     - ``== 0``
2566     - ``!= 0``
2567     - ``i != 0``
2568   * - ``bigint``
2569     - ``== 0n``
2570     - ``!= 0n``
2571     - ``i != 0n``
2572   * - ``null`` or ``undefined``
2573     - ``always``
2574     - ``never``
2575     - ``x != null`` or
2576
2577       ``x != undefined``
2578   * - Union types
2579     - When value is ``false`` according to this column
2580     - When value is ``true`` according to this column
2581     - ``x != null`` or
2582
2583       ``x != undefined`` for union types with nullish types
2584   * - Any other nonNullish type
2585     - ``never``
2586     - ``always``
2587     - ``new SomeType != null``
2588
2589
2590Extended semantics of :ref:`Conditional-And Expression` and
2591:ref:`Conditional-Or Expression` affects the resultant type of expressions
2592as follows:
2593
2594-  A *conditional-and* expression ``A && B`` is of type ``B`` if the result of
2595   ``A`` is handled as ``true``. Otherwise, it is of type ``A``.
2596
2597-  A *conditional-or* expression ``A || B`` is of type ``B`` if the result of
2598   ``A`` is handled as ``false``. Otherwise, it is of type ``A``.
2599
2600The example below illustrates the way this approach works in practice. Any
2601``nonzero`` number is handled as ``true``. The loop continues until it becomes
2602``zero`` that is handled as ``false``:
2603
2604.. code-block-meta:
2605
2606.. code-block:: typescript
2607   :linenos:
2608
2609    for (let i = 10; i; i--) {
2610       console.log (i)
2611    }
2612    /* And the output will be
2613         10
2614         9
2615         8
2616         7
2617         6
2618         5
2619         4
2620         3
2621         2
2622         1
2623     */
2624
2625.. index::
2626   NaN
2627   nullish expression
2628   numeric expression
2629   conditional-and expression
2630   conditional-or expression
2631   loop
2632   string
2633   integer type
2634   union type
2635   nullish type
2636   nonzero
2637
2638.. raw:: pdf
2639
2640   PageBreak
2641