• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# TypeScript to ArkTS Cookbook
2
3Welcome to the "TypeScript to ArkTS" cookbook. This document gives you short
4recipes to rewrite your standard TypeScript code to ArkTS. Although ArkTS is
5designed to be close to TypeScript, some limitations were added for the sake of
6performance. As a result, all TypeScript features can be divided into the following
7categories:
8
9- **Fully supported features**: The original code requires no modification
10   at all. According to our measurements, projects that already follow the
11   best TypeScript practices can keep 90% to 97% of their codebase intact.
12- **Partially supported features**: Some minor code refactoring is needed.
13   Example: The keyword `let` must be used in place of `var` to declare
14   variables. Your code will remain a valid TypeScript code
15   after rewriting by our recipes.
16- **Unsupported features**: A greater code refactoring effort is required.
17   Example: The type `any` is unsupported, and you need to introduce explicit
18   typing to your code everywhere `any` is used.
19
20The document is built on the feature-by-feature basis, and if you do not
21find a specific feature, then you can safely consider it **fully supported**. Otherwise,
22a recipe will give you a suggestion on how to rewrite your code and work
23around an unsupported case.
24
25**Recipe Explained**
26
27The original TypeScript code contains the keyword `var`:
28
29```typescript
30function addTen(x: number): number {
31    var ten = 10
32    return x + ten
33}
34```
35
36The code must be rewritten as follows:
37
38```typescript
39// Important! This is still valid TypeScript code.
40function addTen(x: number): number {
41    let ten = 10
42    return x + ten
43}
44```
45**Severity Levels**
46
47Each recipe is marked with the the severity level. Supported values:
48
49- **Severity: error**: The recipe should be followed, otherwise the program
50  will fail to compile.
51- **Severity: warning**: It is highly recommended to follow the recipe. Although
52  violating the recipe does not currently affect the compilation, in future
53  versions, it will cause compilation to fail.
54
55**Status of Unsupported Features**
56
57Currently, unsupported features are mainly either of the following:
58
59- Features relate to dynamic typing that degrades runtime performance
60- Features that require extra support in the compiler, thereby degrading project build time
61
62However, the ArkTS team reserves the right to reconsider the list and
63**shrink** it in the future releases based on the feedback from developers
64and real-world data experiments.
65
66## Recipes Summarized
67
68This document provides an informal summary of TypeScript features that ArkTS either
69can support with limitations, or cannot support. See [Recipes](#recipes) for the
70full list with more detailed code examples and workaround suggestions.
71
72### Static Typing Is Enforced
73
74ArkTS was designed with the following goals in mind:
75
76- ArkTS programs must be easy for developers to read and understand because
77  the code is read more often than written.
78- ArkTS must execute fast and consume as little power as possible because
79  it is particularly critical on mobile devices that ArkTS targets.
80
81One of the most important features of ArkTS that helps achieving both goals
82is static typing. If a program is statically typed (all types
83are known at compile time), it is much easier to understand what data
84structures are used in the code. Since all types are known before the program
85actually runs, the compiler can verify code correctness, thereby
86eliminating many runtime type checks and improving performance.
87
88Therefore, the usage of the type `any` in ArkTS is prohibited.
89
90**Example**
91
92```typescript
93//
94// Not supported:
95//
96
97let res : any = some_api_function("hello", "world")
98
99// What is `res`? A numeric error code, a string, or an object?
100// How should we work with it?
101
102//
103// Supported:
104//
105
106class CallResult {
107    public succeeded() : boolean { ... }
108    public errorMessage() : string { ... }
109}
110
111let res : CallResult = some_api_function("hello", "world")
112if (!res.succeeded()) {
113    console.log("Call failed: " + res.errorMessage())
114}
115```
116
117According to our measurements, `any` is already not welcome in TypeScript. It is used in approximately 1% of
118TypeScript codebases. Moreover, today's code linters (for example, ESLint) include a set
119of rules that prohibit the usage of `any`. Prohibiting `any` results in a strong positive impact on performance at the cost of low-effort code refactoring.
120
121### Changing Object Layout in Runtime Is Prohibited
122
123To achieve maximum performance benefits, ArkTS requires the layout of objects
124to remain unchanged during program execution. In other words, it is prohibited to:
125
126- Add new properties or methods to objects.
127- Delete existing properties or methods from objects.
128- Assign values of arbitrary types to object properties.
129
130It is noteworthy that many such operations are already prohibited by the TypeScript
131compiler. However, it can still be "tricked", for example, by `as any` casting that
132ArkTS does not support (see the detailed example below).
133
134**Example**
135
136```typescript
137class Point {
138    public x : number = 0
139    public y : number = 0
140
141    constructor(x : number, y : number) {
142        this.x = x
143        this.y = y
144    }
145}
146
147/* It is impossible to delete a property
148   from the object. It is guaranteed that
149   all Point objects have the property x.
150*/
151let p1 = new Point(1.0, 1.0)
152delete p1.x           // Compile-time error in TypeScript and ArkTS
153delete (p1 as any).x  // OK in TypeScript; compile-time error in ArkTS
154
155/* Class Point does not define any property
156   named `z`, and it is impossible to add
157   it while the program runs.
158*/
159let p2 = new Point(2.0, 2.0)
160p2.z = "Label";         // Compile-time error in TypeScript and ArkTS
161(p2 as any).z = "Label" // OK in TypeScript; compile-time error in ArkTS
162
163/* It is guaranteed that all Point objects
164   have only properties x and y, it is
165   impossible to generate some arbitrary
166   identifier and use it as a new property:
167*/
168let p3 = new Point(3.0, 3.0)
169let prop = Symbol();     // OK in TypeScript; compile-time error in ArkTS
170(p3 as any)[prop] = p3.x // OK in TypeScript; compile-time error in ArkTS
171p3[prop] = p3.x          // Compile-time error in TypeScript and ArkTS
172
173/* It is guaranteed that all Point objects
174   have properties x and y of type number,
175   so assigning a value of any other type
176   is impossible:
177*/
178let p4 = new Point(4.0, 4.0)
179p4.x = "Hello!";         // Compile-time error in TypeScript and ArkTS
180(p4 as any).x = "Hello!" // OK in TypeScript; compile-time error in ArkTS
181
182// Usage of Point objects which is compliant with the class definition:
183function distance(p1 : Point, p2 : Point) : number {
184    return Math.sqrt(
185      (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y)
186    )
187}
188let p5 = new Point(5.0, 5.0)
189let p6 = new Point(6.0, 6.0)
190console.log("Distance between p5 and p6: " + distance(p5, p6))
191```
192
193Unpredictable changing of object layout contradicts both good readability and
194good performance of code. Indeed, having class definition at one place and
195modifying actual object layout elsewhere is confusing and error-prone from the
196developer's point of view. It opposes the idea of static typing
197and requires extra runtime support that causes undesired execution overhead.
198
199According to our observations and experiments, this feature is already not
200welcome in TypeScript. It is used in a marginal number of real-world projects,
201and state-of-the-art linters have rules to prohibit its usage.
202
203Prohibiting runtime changes to object layouts results in a
204strong positive impact on performance at the cost of low-effort refactoring.
205
206### Semantics of Operators Is Restricted
207
208To achieve better performance and encourage developers to write clearer code,
209ArkTS restricts the semantics of some operators. An example is
210given below, and the full list of restrictions is outlined in [Recipes](#recipes).
211
212**Example**
213
214```typescript
215// Unary `+` is defined only for numbers, but not for strings:
216console.log(+42) // OK
217console.log(+"42") // Compile-time error
218```
219
220Loading language operators with extra semantics complicates the language
221specification, and forces developers to remember all possible corner cases with
222appropriate handling rules. Besides, in certain cases it causes some undesired
223runtime overhead.
224
225According to our observations and experiments, this feature is not popular in TypeScript. It is used in less than 1% of real-world codebases, and such cases are easy to refactor. Restricting the operator semantics results in a clearer and more performant at the cost of low-effort changes in code.
226
227### Structural Typing Is Not Supported (Yet)
228
229Assuming that two unrelated classes `T` and `U` have the same public API:
230
231```typescript
232class T {
233    public name : string = ""
234
235    public greet() : void {
236        console.log("Hello, " + this.name)
237    }
238}
239
240class U {
241    public name : string = ""
242
243    public greet() : void {
244        console.log("Greetings, " + this.name)
245    }
246}
247```
248
249Can we assign a value of `T` to a variable of `U`?
250
251```typescript
252let u : U = new T() // Is this allowed?
253```
254
255Can we pass a value of `T` to a function that accepts a parameter of `U`?
256
257```typescript
258function greeter(u : U) {
259    console.log("To " + u.name)
260    u.greet()
261}
262
263let t : T = new T()
264greeter(t) // Is this allowed?
265```
266
267In other words, which approach will we take:
268
269- `T` and `U` are not related by inheritance or any common interface, but
270  they are "somewhat equivalent" since they have the same public API, and so
271  the answer to both questions above is "yes".
272- `T` and `U` are not related by inheritance or any common interface, and
273  always must be considered as totally different types, and so the answer to
274  both questions above is "no".
275
276The languages that take the first approach are said to support structural
277typing, whereas the languages that take the second approach do not support it.
278Currently, TypeScript supports structural typing, and ArkTS does not.
279
280It is debatable whether structural typing helps to produce code that
281is clearer and more understandable, and both *pro* and *contra* arguments can
282be found. Moreover, structural typing does not harm program performance (at
283least in some cases). Why does ArkTS not support it then?
284
285The answer is that supporting structural typing is a major feature that needs
286a lot of considerations and careful implementation in language specification,
287compiler, and runtime. As safe and efficient implementation requires taking
288other aspects (static typing and restrictions on changing object layout) into
289account, the support to this feature is postponed. The ArkTS team is ready to reconsider based on real-world scenarios and feedback. More cases and suggested workarounds can be found in [Recipes](#recipes).
290
291## Recipes
292
293### Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
294
295**Rule:** `arkts-identifiers-as-prop-names`
296
297**Severity: error**
298
299ArkTS does not support objects with name properties that are numbers or
300strings. Use classes to access data by property names. Use arrays to access
301data by numeric indices.
302
303**TypeScript**
304
305```typescript
306var x = {"name": 1, 2: 3}
307
308console.log(x["name"])
309console.log(x[2])
310```
311
312**ArkTS**
313
314```typescript
315class X {
316    public name: number = 0
317}
318let x:X = {name: 1}
319console.log(x.name)
320
321let y = [1, 2, 3]
322console.log(y[2])
323
324// If you still need a container to store keys of different types,
325// use Map<Object, some_type>.
326let z = new Map<Object, number>()
327z.set("name", 1)
328z.set(2, 2)
329console.log(z.get("name"))
330console.log(z.get(2))
331```
332
333**See also**
334
335* Recipe: `Symbol()` Is Not Supported
336* Recipe: Indexed Access Is Not Supported for Fields
337* Recipe: `delete` Operator Is Not Supported
338* Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
339* Recipe: `in` Operator Is Not Supported
340* Recipe: Usage of Standard Libraries Is Restricted
341
342### Recipe: `Symbol()` Is Not Supported
343
344**Rule:** `arkts-no-symbol`
345
346**Severity: error**
347
348TypeScript uses the `Symbol()` API among other things to generate
349unique property names at runtime. ArkTS does not support the `Symbol()` API
350because its most popular use cases make no sense in the statically typed
351environment. In particular, the object layout is defined at compile time
352and cannot be changed at runtime.
353
354Only `Symbol.iterator` is supported.
355
356**See also**
357
358* Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
359* Recipe: Indexed Access Is Not Supported for Fields
360* Recipe: `delete` Operator Is Not Supported
361* Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
362* Recipe: `in` Operator Is Not Supported
363* Recipe: Usage of Standard Libraries Is Restricted
364
365### Recipe: Private `#` Identifiers Are Not Supported
366
367**Rule:** `arkts-no-private-identifiers`
368
369**Severity: error**
370
371ArkTS does not use private identifiers starting with the symbol `#`. Use
372the keyword  `private` instead.
373
374**TypeScript**
375
376```typescript
377/*
378 * Such notation for private fields is not supported in ArkTS:
379class C {
380    #foo: number = 42
381}
382*/
383```
384
385**ArkTS**
386
387```typescript
388class C {
389    private foo: number = 42
390}
391```
392
393### Recipe: Use Unique Names for Types and Namespaces
394
395**Rule:** `arkts-unique-names`
396
397**Severity: error**
398
399Names for all types (classes, interfaces, and enums) and namespaces must be unique
400and distinct from other names such as, variable names, and function names.
401
402**TypeScript**
403
404```typescript
405let X: string
406type X = number[] // Type alias with the same name as the variable
407```
408
409**ArkTS**
410
411```typescript
412let X: string
413type T = number[] // X is not allowed here to avoid name collisions.
414```
415
416### Recipe: Use `let` Instead of `var`
417
418**Rule:** `arkts-no-var`
419
420**Severity: error**
421
422ArkTS does not support `var`. Use `let` instead.
423
424**TypeScript**
425
426```typescript
427function f(shouldInitialize: boolean) {
428    if (shouldInitialize) {
429       var x = 10
430    }
431    return x
432}
433
434console.log(f(true))  // 10
435console.log(f(false)) // Undefined
436
437let upper_let = 0
438{
439    var scoped_var = 0
440    let scoped_let = 0
441    upper_let = 5
442}
443scoped_var = 5 // Visible
444scoped_let = 5 // Compile-time error
445```
446
447**ArkTS**
448
449```typescript
450function f(shouldInitialize: boolean): Object {
451    let x: Object = new Object()
452    if (shouldInitialize) {
453        x = 10
454    }
455    return x
456}
457
458console.log(f(true))  // 10
459console.log(f(false)) // {}
460
461let upper_let = 0
462let scoped_var = 0
463{
464    let scoped_let = 0
465    upper_let = 5
466}
467scoped_var = 5
468scoped_let = 5 // Compile-time error
469```
470
471### Recipe: Use Explicit Types Instead of `any` or `unknown`
472
473**Rule:** `arkts-no-any-unknown`
474
475**Severity: error**
476
477ArkTS does not support the types `any` and `unknown`. Specify
478types explicitly.
479
480If your ArkTS code has to interoperate with the standard TypeScript or JavaScript code
481and no type information is available (or the type information is impossible
482to obtain), you can use a special `ESObject` type for working with dynamic
483objects. Please note that such objects reduce type checking (which means less
484stable and more error-prone code) and have severe runtime overhead and
485should be avoided at all cost. Using `ESObject` will still produce a warning
486message.
487
488**TypeScript**
489
490```typescript
491let value1 : any
492value1 = true
493value1 = 42
494
495let value2 : unknown
496value2 = true
497value2 = 42
498
499// Let's assume that we have no information for external_function
500// because it is defined in JavaScript code:
501let something : any = external_function()
502console.log("someProperty of something:", something.someProperty)
503```
504
505**ArkTS**
506
507```typescript
508let value_b: boolean = true // OR: let value_b = true
509let value_n: number = 42 // OR: let value_n = 42
510let value_o1: Object = true
511let value_o2: Object = 42
512
513// Let's assume that we have no information for external_function
514// because it is defined in JavaScript code:
515let something : ESObject = external_function()
516console.log("someProperty of something:", something.someProperty)
517```
518
519**See also**
520
521* Recipe: Strict Type Checking Is Enforced
522
523### Recipe: Use `class` Instead of a Type with a Call Signature
524
525**Rule:** `arkts-no-call-signatures`
526
527**Severity: error**
528
529ArkTS does not support call signatures in object types. Use `class` instead.
530
531**TypeScript**
532
533```typescript
534type DescribableFunction = {
535    description: string
536    (someArg: number): string // Call signature
537}
538
539function doSomething(fn: DescribableFunction): void {
540    console.log(fn.description + " returned " + fn(6))
541}
542```
543
544**ArkTS**
545
546```typescript
547class DescribableFunction {
548    description: string
549    public invoke(someArg: number): string {
550        return someArg.toString()
551    }
552    constructor() {
553        this.description = "desc"
554    }
555}
556
557function doSomething(fn: DescribableFunction): void {
558    console.log(fn.description + " returned " + fn.invoke(6))
559}
560
561doSomething(new DescribableFunction())
562```
563
564**See also**
565
566* Recipe: Use class Instead of a Type with a Constructor Signature
567
568### Recipe: Use `class` Instead of a Type with a Constructor Signature
569
570**Rule:** `arkts-no-ctor-signatures-type`
571
572**Severity: error**
573
574ArkTS does not support constructor signatures in object types. Use `class`
575instead.
576
577**TypeScript**
578
579```typescript
580class SomeObject {}
581
582type SomeConstructor = {
583    new (s: string): SomeObject
584}
585
586function fn(ctor: SomeConstructor) {
587    return new ctor("hello")
588}
589```
590
591**ArkTS**
592
593```typescript
594class SomeObject {
595    public f: string
596    constructor (s: string) {
597        this.f = s
598    }
599}
600
601function fn(s: string): SomeObject {
602    return new SomeObject(s)
603}
604```
605
606**See also**
607
608* Recipe: Use `class` Instead of a Type with a Call Signature
609
610### Recipe: Only One Static Block Is Supported
611
612**Rule:** `arkts-no-multiple-static-blocks`
613
614**Severity: error**
615
616ArkTS does not allow several static blocks for class initialization.
617Combine static block statements into one static block.
618
619**TypeScript**
620
621```typescript
622class C {
623    static s: string
624
625    static {
626        C.s = "aa"
627    }
628    static {
629        C.s = C.s + "bb"
630    }
631}
632```
633
634**ArkTS**
635
636```typescript
637class C {
638    static s: string
639
640    static {
641        C.s = "aa"
642        C.s = C.s + "bb"
643    }
644}
645```
646
647### Recipe: Indexed Signatures Are Not Supported
648
649**Rule:** `arkts-no-indexed-signatures`
650
651**Severity: error**
652
653ArkTS does not allow indexed signatures. Use arrays instead.
654
655**TypeScript**
656
657```typescript
658// Interface with an indexed signature:
659interface StringArray {
660    [index: number]: string
661}
662
663function getStringArray() : StringArray {
664    return ["a", "b", "c"]
665}
666
667const myArray: StringArray = getStringArray()
668const secondItem = myArray[1]
669```
670
671**ArkTS**
672
673```typescript
674class X {
675    public f: string[] = []
676}
677
678let myArray: X = new X()
679const secondItem = myArray.f[1]
680```
681
682### Recipe: Use Inheritance Instead of Intersection Types
683
684**Rule:** `arkts-no-intersection-types`
685
686**Severity: error**
687
688Currently, ArkTS does not support intersection types. Use inheritance
689as a workaround.
690
691**TypeScript**
692
693```typescript
694interface Identity {
695    id: number
696    name: string
697}
698
699interface Contact {
700    email: string
701    phoneNumber: string
702}
703
704type Employee = Identity & Contact
705```
706
707**ArkTS**
708
709```typescript
710interface Identity {
711    id: number
712    name: string
713}
714
715interface Contact {
716    email: string
717    phoneNumber: string
718}
719
720interface Employee extends Identity,  Contact {}
721```
722
723### Recipe: Type Notation Using `this` Is Not Supported
724
725**Rule:** `arkts-no-typing-with-this`
726
727**Severity: error**
728
729ArkTS does not support type notation using the `this` keyword. For example,
730specifying a method's return type `this` is not allowed. Use the explicit type
731instead.
732
733**TypeScript**
734
735```typescript
736interface ListItem {
737    getHead(): this
738}
739
740class C {
741    n: number = 0
742
743    m(c: this) {
744        console.log(c)
745    }
746}
747```
748
749**ArkTS**
750
751```typescript
752interface ListItem {
753    getHead(): ListItem
754}
755
756class C {
757    n: number = 0
758
759    m(c: C) {
760        console.log(c)
761    }
762}
763```
764
765### Recipe: Conditional Types Are Not Supported
766
767**Rule:** `arkts-no-conditional-types`
768
769**Severity: error**
770
771ArkTS does not support conditional type aliases. Introduce a new type with
772constraints explicitly, or rewrite logic using `Object`. The keyword
773`infer` is not supported.
774
775**TypeScript**
776
777```typescript
778type X<T> = T extends number ? T : never
779
780type Y<T> = T extends Array<infer Item> ? Item : never
781```
782
783**ArkTS**
784
785```typescript
786// Provide explicit constraints within type alias.
787type X1<T extends number> = T
788
789// Rewrite with Object. Less type control requires more type checking for safety.
790type X2<T> = Object
791
792// Item has to be used as a generic parameter and needs to be properly
793// instantiated.
794type YI<Item, T extends Array<Item>> = Item
795```
796
797### Recipe: Declaring Fields in `constructor` Is Not Supported
798
799**Rule:** `arkts-no-ctor-prop-decls`
800
801**Severity: error**
802
803ArkTS does not support declaring class fields in `constructor`.
804Declare class fields inside the `class` declaration instead.
805
806**TypeScript**
807
808```typescript
809class Person {
810    constructor(
811        protected ssn: string,
812        private firstName: string,
813        private lastName: string
814    ) {
815        this.ssn = ssn
816        this.firstName = firstName
817        this.lastName = lastName
818    }
819
820    getFullName(): string {
821        return this.firstName + " " + this.lastName
822    }
823}
824```
825
826**ArkTS**
827
828```typescript
829class Person {
830    protected ssn: string
831    private firstName: string
832    private lastName: string
833
834    constructor(ssn: string, firstName: string, lastName: string) {
835        this.ssn = ssn
836        this.firstName = firstName
837        this.lastName = lastName
838    }
839
840    getFullName(): string {
841        return this.firstName + " " + this.lastName
842    }
843}
844```
845
846### Recipe: Constructor Signatures Are Not Supported in Interfaces
847
848**Rule:** `arkts-no-ctor-signatures-iface`
849
850**Severity: error**
851
852ArkTS does not support constructor signatures. Use methods instead.
853
854**TypeScript**
855
856```typescript
857interface I {
858    new (s: string): I
859}
860
861function fn(i: I) {
862    return new i("hello")
863}
864```
865
866**ArkTS**
867
868```typescript
869interface I {
870    create(s: string): I
871}
872
873function fn(i: I) {
874    return i.create("hello")
875}
876```
877
878**See also**
879
880* Recipe: Use `class` Instead of a Type with a Constructor Signature
881
882### Recipe: Indexed Access Types Are Not Supported
883
884**Rule:** `arkts-no-aliases-by-index`
885
886**Severity: error**
887
888ArkTS does not support indexed access types. Use the type name instead.
889
890**TypeScript**
891
892```typescript
893type Point = {x: number, y: number}
894type N = Point["x"] // Equal to number
895```
896
897**ArkTS**
898
899```typescript
900class Point {x: number = 0; y: number = 0}
901type N = number
902```
903
904### Recipe: Indexed Access Is Not Supported for Fields
905
906**Rule:** `arkts-no-props-by-index`
907
908**Severity: error**
909
910ArkTS does not support dynamic field declaration and access. Declare all
911object fields immediately in the class. Access only those class fields
912that are either declared in the class, or accessible via inheritance. Accessing
913any other fields is prohibited, and causes compile-time errors.
914
915To access a field, use the `obj.field` syntax. Indexed access (`obj["field"]`)
916is not supported. An exception is all typed arrays from the standard library
917(for example, `Int32Array`), which support access to their elements through the
918`container[index]` syntax.
919
920**TypeScript**
921
922```typescript
923class Point {
924    x: number = 0
925    y: number = 0
926}
927let p: Point = {x: 1, y: 2}
928console.log(p["x"])
929
930class Person {
931    name: string = ""
932    age: number = 0; // semicolon is required here
933    [key: string]: string | number
934}
935
936let person: Person = {
937    name: "John",
938    age: 30,
939    email: "***@example.com",
940    phoneNumber: "18*********",
941}
942```
943
944**ArkTS**
945
946```typescript
947class Point {
948    x: number = 0
949    y: number = 0
950}
951let p: Point = {x: 1, y: 2}
952console.log(p.x)
953
954class Person {
955    name: string
956    age: number
957    email: string
958    phoneNumber: string
959
960    constructor(name: string, age: number, email: string,
961                phoneNumber: string) {
962        this.name = name
963        this.age = age
964        this.email = email
965        this.phoneNumber = phoneNumber
966    }
967}
968
969let person = new Person("John", 30, "***@example.com", "18*********")
970console.log(person["name"])         // Compile-time error
971console.log(person.unknownProperty) // Compile-time error
972
973let arr = new Int32Array(1)
974console.log(arr[0])
975```
976
977### Recipe: Structural Typing Is Not Supported
978
979**Rule:** `arkts-no-structural-typing`
980
981**Severity: error**
982
983Currently, ArkTS does not support structural typing. This means that  the compiler
984cannot compare public APIs of two types and decide whether they are
985identical. Use other mechanisms (inheritance, interfaces, or type aliases)
986instead.
987
988**TypeScript**
989
990```typescript
991interface I1 {
992    f(): string
993}
994
995interface I2 { // I2 is structurally equivalent to I1.
996    f(): string
997}
998
999class X {
1000    n: number = 0
1001    s: string = ""
1002}
1003
1004class Y { // Y is structurally equivalent to X.
1005    n: number = 0
1006    s: string = ""
1007}
1008
1009let x = new X()
1010let y = new Y()
1011
1012console.log("Assign X to Y")
1013y = x
1014
1015console.log("Assign Y to X")
1016x = y
1017
1018function foo(x: X) {
1019    console.log(x.n, x.s)
1020}
1021
1022// X and Y are equivalent because their public API is equivalent.
1023// Therefore, the second call is allowed.
1024foo(new X())
1025foo(new Y())
1026```
1027
1028**ArkTS**
1029
1030```typescript
1031interface I1 {
1032    f(): string
1033}
1034
1035type I2 = I1 // I2 is an alias for I1.
1036
1037class B {
1038    n: number = 0
1039    s: string = ""
1040}
1041
1042// D is derived from B, which explicitly set subtype/supertype relations.
1043class D extends B {
1044    constructor() {
1045        super()
1046    }
1047}
1048
1049let b = new B()
1050let d = new D()
1051
1052console.log("Assign D to B")
1053b = d // OK. B is the superclass of D.
1054
1055// An attempt to assign b to d will result in a compile-time error.
1056// d = b
1057
1058interface Z {
1059   n: number
1060   s: string
1061}
1062
1063// X implements interface Z, which makes relation between X and Y explicit.
1064class X implements Z {
1065    n: number = 0
1066    s: string = ""
1067}
1068
1069// Y implements interface Z, which makes relation between X and Y explicit.
1070class Y implements Z {
1071    n: number = 0
1072    s: string = ""
1073}
1074
1075let x: Z = new X()
1076let y: Z = new Y()
1077
1078console.log("Assign X to Y")
1079y = x // ok, both are of the same type
1080
1081console.log("Assign Y to X")
1082x = y // ok, both are of the same type
1083
1084function foo(c: Z): void {
1085    console.log(c.n, c.s)
1086}
1087
1088// X and Y implement the same interface. Therefore both calls are allowed.
1089foo(new X())
1090foo(new Y())
1091```
1092
1093### Recipe: Type Inference in Case of Generic Function Calls Is Limited
1094
1095**Rule:** `arkts-no-inferred-generic-params`
1096
1097**Severity: error**
1098
1099ArkTS allows to omit generic type parameters if it is possible to infer
1100the concrete types from the parameters passed to the function. A compile-time
1101error occurs otherwise. In particular, inference of generic type parameters
1102based only on function return types is prohibited.
1103
1104**TypeScript**
1105
1106```typescript
1107function choose<T>(x: T, y: T): T {
1108    return Math.random() < 0.5 ? x : y
1109}
1110
1111let x = choose(10, 20)   // OK. choose<number>(...) is inferred.
1112let y = choose("10", 20) // Compile-time error
1113
1114function greet<T>(): T {
1115    return "Hello" as T
1116}
1117let z = greet() // Type of T is inferred as "unknown".
1118```
1119
1120**ArkTS**
1121
1122```typescript
1123function choose<T>(x: T, y: T): T {
1124    return Math.random() < 0.5 ? x : y
1125}
1126
1127let x = choose(10, 20)   // OK. choose<number>(...) is inferred.
1128let y = choose("10", 20) // Compile-time error
1129
1130function greet<T>(): T {
1131    return "Hello" as T
1132}
1133let z = greet<string>()
1134```
1135
1136### Recipe: RegExp Literals Are Not Supported
1137
1138**Rule:** `arkts-no-regexp-literals`
1139
1140**Severity: error**
1141
1142Currently, ArkTS does not support regular expression literals. Use library calls with
1143string literals instead.
1144
1145**TypeScript**
1146
1147```typescript
1148let regex: RegExp = /bc*d/
1149```
1150
1151**ArkTS**
1152
1153```typescript
1154let regex: RegExp = new RegExp('bc*d')
1155```
1156
1157### Recipe: Object Literal Must Correspond to Some Explicitly Declared Class or Interface
1158
1159**Rule:** `arkts-no-untyped-obj-literals`
1160
1161**Severity: error**
1162
1163ArkTS supports usage of object literals if the compiler can infer to the
1164classes or interfaces that such literals correspond to. Otherwise, a compile-time error
1165occurs. Using literals to initialize classes and interfaces is
1166specifically not supported in the following contexts:
1167
1168* Initialization of anything that has `any`, `Object`, or `object` type
1169* Initialization of classes or interfaces with methods
1170* Initialization of classes which declare a `constructor` with parameters
1171* Initialization of classes with `readonly` fields
1172
1173**TypeScript**
1174
1175```typescript
1176let o1 = {n: 42, s: "foo"}
1177let o2: Object = {n: 42, s: "foo"}
1178let o3: object = {n: 42, s: "foo"}
1179
1180let oo: Object[] = [{n: 1, s: "1"}, {n: 2, s: "2"}]
1181
1182class C2 {
1183    s: string
1184    constructor(s: string) {
1185        this.s = "s =" + s
1186    }
1187}
1188let o4: C2 = {s: "foo"}
1189
1190class C3 {
1191    readonly n: number = 0
1192    readonly s: string = ""
1193}
1194let o5: C3 = {n: 42, s: "foo"}
1195
1196abstract class A {}
1197let o6: A = {}
1198
1199class C4 {
1200    n: number = 0
1201    s: string = ""
1202    f() {
1203        console.log("Hello")
1204    }
1205}
1206let o7: C4 = {n: 42, s: "foo", f : () => {}}
1207
1208class Point {
1209    x: number = 0
1210    y: number = 0
1211}
1212
1213function id_x_y(o: Point): Point {
1214    return o
1215}
1216
1217// Structural typing is used to deduce that p is Point.
1218let p = {x: 5, y: 10}
1219id_x_y(p)
1220
1221// A literal can be contextually (i.e., implicitly) typed as Point.
1222id_x_y({x: 5, y: 10})
1223```
1224
1225**ArkTS**
1226
1227```typescript
1228class C1 {
1229    n: number = 0
1230    s: string = ""
1231}
1232
1233let o1: C1 = {n: 42, s: "foo"}
1234let o2: C1 = {n: 42, s: "foo"}
1235let o3: C1 = {n: 42, s: "foo"}
1236
1237let oo: C1[] = [{n: 1, s: "1"}, {n: 2, s: "2"}]
1238
1239class C2 {
1240    s: string
1241    constructor(s: string) {
1242        this.s = "s =" + s
1243    }
1244}
1245let o4 = new C2("foo")
1246
1247class C3 {
1248    n: number = 0
1249    s: string = ""
1250}
1251let o5: C3 = {n: 42, s: "foo"}
1252
1253abstract class A {}
1254class C extends A {}
1255let o6: C = {} // or let o6: C = new C()
1256
1257class C4 {
1258    n: number = 0
1259    s: string = ""
1260    f() {
1261        console.log("Hello")
1262    }
1263}
1264let o7 = new C4()
1265o7.n = 42
1266o7.s = "foo"
1267
1268class Point {
1269    x: number = 0
1270    y: number = 0
1271
1272    // constructor() is used before literal initialization
1273    // to create a valid object. Since there is no other Point constructors,
1274    // constructor() is automatically added by compiler.
1275}
1276
1277function id_x_y(o: Point): Point {
1278    return o
1279}
1280
1281// Explicit type is required for literal initialization.
1282let p: Point = {x: 5, y: 10}
1283id_x_y(p)
1284
1285// id_x_y expects Point explicitly.
1286// A new instance of Point is initialized with the literal.
1287id_x_y({x: 5, y: 10})
1288```
1289
1290**See also**
1291
1292* Recipe: Object Literals Cannot Be Used as Type Declarations
1293* Recipe: Array Literals Must Contain Elements of Only Inferrable Types
1294
1295### Recipe: Object Literals Cannot Be Used as Type Declarations
1296
1297**Rule:** `arkts-no-obj-literals-as-types`
1298
1299**Severity: error**
1300
1301ArkTS does not support the usage of object literals to declare
1302types in place. Declare classes and interfaces explicitly instead.
1303
1304**TypeScript**
1305
1306```typescript
1307let o: {x: number, y: number} = {
1308    x: 2,
1309    y: 3
1310}
1311
1312type S = Set<{x: number, y: number}>
1313```
1314
1315**ArkTS**
1316
1317```typescript
1318class O {
1319    x: number = 0
1320    y: number = 0
1321}
1322
1323let o: O = {x: 2, y: 3}
1324
1325type S = Set<O>
1326```
1327
1328**See also**
1329
1330* Recipe: Object Literal Must Correspond to Some Explicitly Declared Class or Interface
1331* Recipe: Array Literals Must Contain Elements of Only Inferrable Types
1332
1333### Recipe: Array Literals Must Contain Elements of Only Inferrable Types
1334
1335**Rule:** `arkts-no-noninferrable-arr-literals`
1336
1337**Severity: error**
1338
1339Basically, ArkTS infers the type of an array literal as a union type of its
1340contents. However, a compile-time error occurs if there is at least one
1341element with a non-inferrable type (for example, untyped object literal).
1342
1343**TypeScript**
1344
1345```typescript
1346let a = [{n: 1, s: "1"}, {n: 2, s : "2"}]
1347```
1348
1349**ArkTS**
1350
1351```typescript
1352class C {
1353    n: number = 0
1354    s: string = ""
1355}
1356
1357let a1 = [{n: 1, s: "1"} as C, {n: 2, s : "2"} as C] // a1 is of type "C[]"
1358let a2: C[] = [{n: 1, s: "1"}, {n: 2, s : "2"}]      // ditto
1359```
1360
1361**See also**
1362
1363* Recipe: Object Literal Must Correspond to Some Explicitly Declared Class or Interface
1364* Recipe: Object Literals Cannot Be Used as Type Declarations
1365
1366### Recipe: Use Arrow Functions Instead of Function Expressions
1367
1368**Rule:** `arkts-no-func-expressions`
1369
1370**Severity: error**
1371
1372ArkTS does not support function expressions. Use arrow functions instead
1373to specify explicitly.
1374
1375**TypeScript**
1376
1377```typescript
1378let f = function (s: string) {
1379    console.log(s)
1380}
1381```
1382
1383**ArkTS**
1384
1385```typescript
1386let f = (s: string) => {
1387    console.log(s)
1388}
1389```
1390
1391### Recipe: Use Generic Functions Instead of Generic Arrow Functions
1392
1393**Rule:** `arkts-no-generic-lambdas`
1394
1395**Severity: error**
1396
1397ArkTS does not support generic arrow functions. Use normal generic functions
1398instead.
1399
1400**TypeScript**
1401
1402```typescript
1403let generic_arrow_func = <T extends String> (x: T) => { return x }
1404
1405generic_arrow_func("string")
1406```
1407
1408**ArkTS**
1409
1410```typescript
1411function generic_func<T extends String>(x: T): T {
1412    return x
1413}
1414
1415generic_func<String>("string")
1416```
1417
1418### Recipe: Class Literals Are Not Supported
1419
1420**Rule:** `arkts-no-class-literals`
1421
1422**Severity: error**
1423
1424ArkTS does not support class literals. Introduce new named class types
1425explicitly.
1426
1427**TypeScript**
1428
1429```typescript
1430const Rectangle = class {
1431    constructor(height: number, width: number) {
1432        this.height = height
1433        this.width = width
1434    }
1435
1436    height
1437    width
1438}
1439
1440const rectangle = new Rectangle(0.0, 0.0)
1441```
1442
1443**ArkTS**
1444
1445```typescript
1446class Rectangle {
1447    constructor(height: number, width: number) {
1448        this.height = height
1449        this.width = width
1450    }
1451
1452    height: number
1453    width: number
1454}
1455
1456const rectangle = new Rectangle(0.0, 0.0)
1457```
1458
1459### Recipe: Classes Cannot Be Specified in the `implements` Clause
1460
1461**Rule:** `arkts-implements-only-iface`
1462
1463**Severity: error**
1464
1465ArkTS does not allow to specify a class in the `implements` clause. Only interfaces
1466may be specified.
1467
1468**TypeScript**
1469
1470```typescript
1471class C {
1472  foo() {}
1473}
1474
1475class C1 implements C {
1476  foo() {}
1477}
1478```
1479
1480**ArkTS**
1481
1482```typescript
1483interface C {
1484  foo(): void
1485}
1486
1487class C1 implements C {
1488  foo() {}
1489}
1490```
1491
1492### Recipe: Reassigning Object Methods Is Not Supported
1493
1494**Rule:** `arkts-no-method-reassignment`
1495
1496**Severity: error**
1497
1498ArkTS does not support reassigning a method for objects. In the statically
1499typed languages, the layout of objects is fixed and all instances of the same
1500object must share the same code of each method.
1501
1502If you need to add specific behavior for certain objects, you can create
1503separate wrapper functions or use inheritance.
1504
1505**TypeScript**
1506
1507```typescript
1508class C {
1509    foo() {
1510        console.log("foo")
1511    }
1512}
1513
1514function bar() {
1515    console.log("bar")
1516}
1517
1518let c1 = new C()
1519let c2 = new C()
1520c2.foo = bar
1521
1522c1.foo() // foo
1523c2.foo() // bar
1524```
1525
1526**ArkTS**
1527
1528```typescript
1529class C {
1530    foo() {
1531        console.log("foo")
1532    }
1533}
1534
1535class Derived extends C {
1536    foo() {
1537        console.log("Extra")
1538        super.foo()
1539    }
1540}
1541
1542function bar() {
1543    console.log("bar")
1544}
1545
1546let c1 = new C()
1547let c2 = new C()
1548c1.foo() // foo
1549c2.foo() // foo
1550
1551let c3 = new Derived()
1552c3.foo() // Extra foo
1553```
1554### Recipe: Only the `as T` Syntax Is Supported for Type Casting
1555
1556**Rule:** `arkts-as-casts`
1557
1558**Severity: error**
1559
1560ArkTS supports the keyword `as` as the only syntax for type casting.
1561Incorrect casting causes a compile-time error or runtime `ClassCastException`.
1562The `<type>` syntax for type casting is not supported.
1563
1564Use the expression `new ...` instead of `as` if a **primitive** type
1565(such as a `number` or a `boolean`) must be cast to the reference type.
1566
1567**TypeScript**
1568
1569```typescript
1570class Shape {}
1571class Circle extends Shape {x: number = 5}
1572class Square extends Shape {y: string = "a"}
1573
1574function createShape(): Shape {
1575    return new Circle()
1576}
1577
1578let c1 = <Circle> createShape()
1579
1580let c2 = createShape() as Circle
1581
1582// No report is provided during compilation
1583// or runtime if casting is wrong.
1584let c3 = createShape() as Square
1585console.log(c3.y) // Undefined
1586
1587// Important corner case for casting primitives to the boxed counterparts:
1588// The left operand is not properly boxed here in runtime
1589// because "as" has no runtime effect in TypeScript.
1590let e1 = (5.0 as Number) instanceof Number // false
1591
1592// A Number object is created and instanceof works as expected.
1593let e2 = (new Number(5.0)) instanceof Number // True
1594```
1595
1596**ArkTS**
1597
1598```typescript
1599class Shape {}
1600class Circle extends Shape {x: number = 5}
1601class Square extends Shape {y: string = "a"}
1602
1603function createShape(): Shape {
1604    return new Circle()
1605}
1606
1607let c2 = createShape() as Circle
1608
1609// ClassCastException is thrown during runtime.
1610let c3 = createShape() as Square
1611
1612// A Number object is created and instanceof works as expected.
1613let e2 = (new Number(5.0)) instanceof Number // True
1614```
1615
1616### Recipe: JSX Expressions Are Not Supported
1617
1618**Rule:** `arkts-no-jsx`
1619
1620**Severity: error**
1621
1622Do not use JSX since no alternative is provided to rewrite it.
1623
1624### Recipe: Unary Operators `+`, `-`, and `~` Work Only on Numbers
1625
1626**Rule:** `arkts-no-polymorphic-unops`
1627
1628**Severity: error**
1629
1630ArkTS allows unary operators to work on numeric types only. A compile-time
1631error occurs if these operators are applied to a non-numeric type. Unlike in
1632TypeScript, implicit casting of strings in this context is not supported and casting must
1633be done explicitly.
1634
1635**TypeScript**
1636
1637```typescript
1638let a = +5        // 5 as number
1639let b = +"5"      // 5 as number
1640let c = -5        // -5 as number
1641let d = -"5"      // -5 as number
1642let e = ~5        // -6 as number
1643let f = ~"5"      // -6 as number
1644let g = +"string" // NaN as number
1645
1646function returnTen(): string {
1647    return "-10"
1648}
1649
1650function returnString(): string {
1651    return "string"
1652}
1653
1654let x = +returnTen()    // -10 as number
1655let y = +returnString() // NaN
1656```
1657
1658**ArkTS**
1659
1660```typescript
1661let a = +5        // 5 as number
1662let b = +"5"      // Compile-time error
1663let c = -5        // -5 as number
1664let d = -"5"      // Compile-time error
1665let e = ~5        // -6 as number
1666let f = ~"5"      // Compile-time error
1667let g = +"string" // Compile-time error
1668
1669function returnTen(): string {
1670    return "-10"
1671}
1672
1673function returnString(): string {
1674    return "string"
1675}
1676
1677let x = +returnTen()    // Compile-time error
1678let y = +returnString() // Compile-time error
1679```
1680
1681### Recipe: `delete` Operator Is Not Supported
1682
1683**Rule:** `arkts-no-delete`
1684
1685**Severity: error**
1686
1687ArkTS assumes that object layout is known at compile time and cannot be
1688changed at runtime. Therefore, the operation of deleting a property makes no sense.
1689
1690**TypeScript**
1691
1692```typescript
1693class Point {
1694    x?: number = 0.0
1695    y?: number = 0.0
1696}
1697
1698let p = new Point()
1699delete p.y
1700```
1701
1702**ArkTS**
1703
1704```typescript
1705// To mimic the original semantics, you may declare a nullable type
1706// and assign null to mark the value absence.
1707
1708class Point {
1709    x: number | null = 0
1710    y: number | null = 0
1711}
1712
1713let p = new Point()
1714p.y = null
1715```
1716
1717**See also**
1718
1719* Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
1720* Recipe: `Symbol()` Is Not Supported
1721* Recipe: Indexed Access Is Not Supported for Fields
1722* Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
1723* Recipe: `in` Operator Is Not Supported
1724
1725### Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
1726
1727**Rule:** `arkts-no-type-query`
1728
1729**Severity: error**
1730
1731ArkTS supports the `typeof` operator only in the expression context. Using
1732`typeof` to specify type notations is not supported.
1733
1734**TypeScript**
1735
1736```typescript
1737let n1 = 42
1738let s1 = "foo"
1739console.log(typeof n1) // "number"
1740console.log(typeof s1) // "string"
1741let n2: typeof n1
1742let s2: typeof s1
1743```
1744
1745**ArkTS**
1746
1747```typescript
1748let n1 = 42
1749let s1 = "foo"
1750console.log(typeof n1) // "number"
1751console.log(typeof s1) // "string"
1752let n2: number
1753let s2: string
1754```
1755
1756**See also**
1757
1758* Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
1759* Recipe: `Symbol()` Is Not Supported
1760* Recipe: Indexed Access Is Not Supported for Fields
1761* Recipe: `delete` Operator Is Not Supported
1762* Recipe: `in` Operator Is Not Supported
1763* Recipe: Usage of Standard Libraries Is Restricted
1764
1765### Recipe: `instanceof` Operator Is Partially Supported
1766
1767**Rule:** `arkts-instanceof-ref-types`
1768
1769**Severity: error**
1770
1771In TypeScript, the left-hand side of an `instanceof` expression must be of the type
1772`any`, an object type, or a type parameter. Otherwise, the result is `false`.
1773In ArkTS, the left-hand side of an expression may be of any reference type. Otherwise,
1774a compile-time error occurs. In addition, the left operand in ArkTS
1775cannot be a type.
1776
1777**TypeScript**
1778
1779```typescript
1780class X {
1781    // ...
1782}
1783
1784let a = (new X()) instanceof Object // True
1785let b = (new X()) instanceof X      // True
1786
1787let c = X instanceof Object // True. The left operand is a type.
1788let d = X instanceof X      // False. The left operand is a type.
1789```
1790
1791**ArkTS**
1792
1793```typescript
1794class X {
1795    // ...
1796}
1797
1798let a = (new X()) instanceof Object // True
1799let b = (new X()) instanceof X      // True
1800
1801let c = X instanceof Object // Compile-time error. The left operand is a type.
1802let d = X instanceof X      // Compile-time error. The left operand is a type.
1803```
1804
1805### Recipe: `in` Operator Is Not Supported
1806
1807**Rule:** `arkts-no-in`
1808
1809**Severity: error**
1810
1811ArkTS does not support the operator `in`. This operator makes
1812little sense since the object layout is known at compile time and cannot
1813be changed at runtime. Use `instanceof` as a workaround if you want
1814to check whether certain class members exist.
1815
1816**TypeScript**
1817
1818```typescript
1819class Person {
1820    name: string = ""
1821}
1822let p = new Person()
1823
1824let b = "name" in p // True
1825```
1826
1827**ArkTS**
1828
1829```typescript
1830class Person {
1831    name: string = ""
1832}
1833let p = new Person()
1834
1835let b = p instanceof Person // True. "name" is guaranteed to be present.
1836```
1837
1838**See also**
1839
1840* Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
1841* Recipe: `Symbol()` Is Not Supported
1842* Recipe: Indexed Access Is Not Supported for Fields
1843* Recipe: `delete` Operator Is Not Supported
1844* Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
1845* Recipe: Usage of Standard Libraries Is Restricted
1846
1847### Recipe: Destructuring Assignment Is Not Supported
1848
1849**Rule:** `arkts-no-destruct-assignment`
1850
1851**Severity: error**
1852
1853ArkTS does not support destructuring assignment. Use other idioms (for example,
1854a temporary variable, where applicable) instead.
1855
1856**TypeScript**
1857
1858```typescript
1859let [one, two] = [1, 2]; // Semicolon is required here
1860[one, two] = [two, one]
1861
1862let head, tail
1863[head, ...tail] = [1, 2, 3, 4]
1864```
1865
1866**ArkTS**
1867
1868```typescript
1869let arr: number[] = [1, 2]
1870let one = arr[0]
1871let two = arr[1]
1872
1873let tmp = one
1874one = two
1875two = tmp
1876
1877let data: Number[] = [1, 2, 3, 4]
1878let head = data[0]
1879let tail: Number[] = []
1880for (let i = 1; i < data.length; ++i) {
1881    tail.push(data[i])
1882}
1883```
1884
1885### Recipe: Comma Operator `,` Is Supported Only in `for` Loops
1886
1887**Rule:** `arkts-no-comma-outside-loops`
1888
1889**Severity: error**
1890
1891ArkTS supports the comma operator `,` only in `for` loops. In other cases,
1892the comma operator is useless as it makes the execution order harder to understand.
1893
1894Please note that this rule is applied only to the "comma operator". Other cases, when
1895comma is used to delimit variable declarations or parameters of a function call, are
1896of course allowed.
1897
1898**TypeScript**
1899
1900```typescript
1901for (let i = 0, j = 0; i < 10; ++i, j += 2) {
1902    console.log(i)
1903    console.log(j)
1904}
1905
1906let x = 0
1907x = (++x, x++) // 1
1908```
1909
1910**ArkTS**
1911
1912```typescript
1913for (let i = 0, j = 0; i < 10; ++i, j += 2) {
1914    console.log(i)
1915    console.log(j)
1916}
1917
1918// Use the explicit execution order instead of the comma operator.
1919let x = 0
1920++x
1921x = x++
1922```
1923
1924### Recipe: Destructuring Variable Declarations Are Not Supported
1925
1926**Rule:** `arkts-no-destruct-decls`
1927
1928**Severity: error**
1929
1930ArkTS does not support destructuring variable declarations. This is a dynamic
1931feature relying on structural compatibility. In addition, names in destructuring
1932declarations must be equal to properties within destructed classes.
1933
1934**TypeScript**
1935
1936```typescript
1937class Point {
1938    x: number = 0.0
1939    y: number = 0.0
1940}
1941
1942function returnZeroPoint(): Point {
1943    return new Point()
1944}
1945
1946let {x, y} = returnZeroPoint()
1947```
1948
1949**ArkTS**
1950
1951```typescript
1952class Point {
1953    x: number = 0.0
1954    y: number = 0.0
1955}
1956
1957function returnZeroPoint(): Point {
1958    return new Point()
1959}
1960
1961// Create an intermediate object and work with it field by field
1962// without name restrictions.
1963let zp = returnZeroPoint()
1964let x = zp.x
1965let y = zp.y
1966```
1967
1968### Recipe: Type Annotation in the Catch Clause Is Not Supported
1969
1970**Rule:** `arkts-no-types-in-catch`
1971
1972**Severity: error**
1973
1974In TypeScript, the catch clause variable type annotation must be `any` or `unknown`
1975if specified. As ArkTS does not support these types, omit type annotations.
1976
1977**TypeScript**
1978
1979```typescript
1980try {
1981    // Some code
1982}
1983catch (a: unknown) {
1984    // Handle errors.
1985}
1986```
1987
1988**ArkTS**
1989
1990```typescript
1991try {
1992    // Some code
1993}
1994catch (a) {
1995    // Handle errors.
1996}
1997```
1998
1999**See also**
2000
2001* Recipe: `throw` Statements Do Not Accept Values of Arbitrary Types
2002
2003### Recipe: `for .. in` Is Not Supported
2004
2005**Rule:** `arkts-no-for-in`
2006
2007**Severity: error**
2008
2009ArkTS does not support iteration over object contents by the
2010`for .. in` loop. For objects, iteration over properties at runtime is
2011considered redundant because object layout is known at compile time and
2012cannot change at runtime. For arrays, use the regular `for` loop for iteration.
2013
2014**TypeScript**
2015
2016```typescript
2017let a: number[] = [1.0, 2.0, 3.0]
2018for (let i in a) {
2019    console.log(a[i])
2020}
2021```
2022
2023**ArkTS**
2024
2025```typescript
2026let a: number[] = [1.0, 2.0, 3.0]
2027for (let i = 0; i < a.length; ++i) {
2028    console.log(a[i])
2029}
2030```
2031
2032### Recipe: Mapped Type Expression Is Not Supported
2033
2034**Rule:** `arkts-no-mapped-types`
2035
2036**Severity: error**
2037
2038ArkTS does not support mapped types. Use other language idioms and regular
2039classes to achieve the same behaviour.
2040
2041**TypeScript**
2042
2043```typescript
2044type OptionsFlags<Type> = {
2045    [Property in keyof Type]: boolean
2046}
2047```
2048
2049**ArkTS**
2050
2051```typescript
2052class C {
2053    n: number = 0
2054    s: string = ""
2055}
2056
2057class CFlags {
2058    n: boolean = false
2059    s: boolean = false
2060}
2061```
2062
2063### Recipe: `with` Statement Is Not Supported
2064
2065**Rule:** `arkts-no-with`
2066
2067**Severity: error**
2068
2069ArkTS does not support the `with` statement. Use other language idioms
2070(including fully qualified names of functions) to achieve the same behaviour.
2071
2072**TypeScript**
2073
2074```typescript
2075with (Math) { // Compile-time error, but JavaScript code can still be emitted.
2076    let r: number = 42
2077    console.log("Area: ", PI * r * r)
2078}
2079```
2080
2081**ArkTS**
2082
2083```typescript
2084let r: number = 42
2085console.log("Area: ", Math.PI * r * r)
2086```
2087
2088### Recipe: `throw` Statements Do Not Accept Values of Arbitrary Types
2089
2090**Rule:** `arkts-limited-throw`
2091
2092**Severity: error**
2093
2094ArkTS supports throwing only objects of the class `Error` or any
2095derived class. Throwing an arbitrary type (for example, a `number` or `string`)
2096is prohibited.
2097
2098**TypeScript**
2099
2100```typescript
2101throw 4
2102throw ""
2103throw new Error()
2104```
2105
2106**ArkTS**
2107
2108```typescript
2109throw new Error()
2110```
2111
2112### Recipe: Function Return Type Inference Is Limited
2113
2114**Rule:** `arkts-no-implicit-return-types`
2115
2116**Severity: error**
2117
2118ArkTS supports type inference for function return types, but this functionality
2119is currently restricted. In particular, when the expression in the `return`
2120statement is a call to a function or method whose return value type is omitted,
2121a compile-time error occurs. If this is the case, specify the return type explicitly.
2122
2123**TypeScript**
2124
2125```typescript
2126// Compile-time error when noImplicitAny is enabled.
2127function f(x: number) {
2128    if (x <= 0) {
2129        return x
2130    }
2131    return g(x)
2132}
2133
2134// Compile-time error when noImplicitAny is enabled.
2135function g(x: number) {
2136    return f(x - 1)
2137}
2138
2139function doOperation(x: number, y: number) {
2140    return x + y
2141}
2142
2143console.log(f(10))
2144console.log(doOperation(2, 3))
2145```
2146
2147**ArkTS**
2148
2149```typescript
2150// An explicit return type is required.
2151function f(x: number) : number {
2152    if (x <= 0) {
2153        return x
2154    }
2155    return g(x)
2156}
2157
2158// Return type may be omitted. It is inferred from f's explicit type.
2159function g(x: number) {
2160    return f(x - 1)
2161}
2162
2163// In this case, the return type will be inferred.
2164function doOperation(x: number, y: number) {
2165    return x + y
2166}
2167
2168console.log(f(10))
2169console.log(doOperation(2, 3))
2170```
2171
2172### Recipe: Destructuring Parameter Declarations Are Not Supported
2173
2174**Rule:** `arkts-no-destruct-params`
2175
2176**Severity: error**
2177
2178ArkTS requires parameters to be passed directly to the function, and
2179local names to be assigned manually.
2180
2181**TypeScript**
2182
2183```typescript
2184function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) {
2185    console.log(text)
2186    console.log(x)
2187    console.log(y)
2188    console.log(bold)
2189}
2190
2191drawText({ text: "Hello, world!", location: [100, 50], bold: true })
2192```
2193
2194**ArkTS**
2195
2196```typescript
2197function drawText(text: String, location: number[], bold: boolean) {
2198    let x = location[0]
2199    let y = location[1]
2200    console.log(text)
2201    console.log(x)
2202    console.log(y)
2203    console.log(bold)
2204}
2205
2206function main() {
2207    drawText("Hello, world!", [100, 50], true)
2208}
2209```
2210
2211### Recipe: Nested Functions Are Not Supported
2212
2213**Rule:** `arkts-no-nested-funcs`
2214
2215**Severity: error**
2216
2217ArkTS does not support nested functions. Use lambdas instead.
2218
2219**TypeScript**
2220
2221```typescript
2222function addNum(a: number, b: number): void {
2223
2224    // Nested function
2225    function logToConsole(message: String): void {
2226        console.log(message)
2227    }
2228
2229    let result = a + b
2230
2231    // Invoke the nested function.
2232    logToConsole("result is " + result)
2233}
2234```
2235
2236**ArkTS**
2237
2238```typescript
2239function addNum(a: number, b: number): void {
2240    // Use lambda instead of a nested function.
2241    let logToConsole: (message: string) => void = (message: string): void => {
2242        console.log(message)
2243    }
2244
2245    let result = a + b
2246
2247    logToConsole("result is " + result)
2248}
2249```
2250
2251### Recipe: Using `this` Inside Stand-Alone Functions Is Not Supported
2252
2253**Rule:** `arkts-no-standalone-this`
2254
2255**Severity: error**
2256
2257ArkTS does not support the usage of `this` inside stand-alone functions and
2258inside static methods. `this` can be used in instance methods only.
2259
2260**TypeScript**
2261
2262```typescript
2263function foo(i: number) {
2264    this.count = i // Compile-time error only when noImplicitThis is enabled.
2265}
2266
2267class A {
2268    count: number = 1
2269    m = foo
2270}
2271
2272let a = new A()
2273console.log(a.count) // Prints "1".
2274a.m(2)
2275console.log(a.count) // Prints "2".
2276```
2277
2278**ArkTS**
2279
2280```typescript
2281class A {
2282    count: number = 1
2283    m(i: number): void {
2284        this.count = i
2285    }
2286}
2287
2288function main(): void {
2289    let a = new A()
2290    console.log(a.count)  // Prints "1".
2291    a.m(2)
2292    console.log(a.count)  // Prints "2".
2293}
2294```
2295
2296**See also**
2297
2298* Recipe: `Function.apply`, `Function.bind`, and `Function.call` Are Not Supported
2299
2300### Recipe: Generator Functions Are Not Supported
2301
2302**Rule:** `arkts-no-generators`
2303
2304**Severity: error**
2305
2306Currently, ArkTS does not support generator functions.
2307Use the `async`/`await` mechanism for multitasking.
2308
2309**TypeScript**
2310
2311```typescript
2312function* counter(start: number, end: number) {
2313    for (let i = start; i <= end; i++) {
2314        yield i
2315    }
2316}
2317
2318for (let num of counter(1, 5)) {
2319    console.log(num)
2320}
2321```
2322
2323**ArkTS**
2324
2325```typescript
2326async function complexNumberProcessing(n : number) : Promise<number> {
2327    // Some complex logic for processing the number here
2328    return n
2329}
2330
2331async function foo() {
2332    for (let i = 1; i <= 5; i++) {
2333        console.log(await complexNumberProcessing(i))
2334    }
2335}
2336
2337foo()
2338```
2339
2340### Recipe: Type Guarding Is Supported with `instanceof` and `as`
2341
2342**Rule:** `arkts-no-is`
2343
2344**Severity: error**
2345
2346ArkTS does not support the `is` operator, which must be replaced by the
2347`instanceof` operator. Note that the fields of an object must be cast to the
2348appropriate type with the `as` operator before being used.
2349
2350**TypeScript**
2351
2352```typescript
2353class Foo {
2354    foo: number = 0
2355    common: string = ""
2356}
2357
2358class Bar {
2359    bar: number = 0
2360    common: string = ""
2361}
2362
2363function isFoo(arg: any): arg is Foo {
2364    return arg.foo !== undefined
2365}
2366
2367function doStuff(arg: Foo | Bar) {
2368    if (isFoo(arg)) {
2369        console.log(arg.foo)    // OK
2370        console.log(arg.bar)    // Compile-time error
2371    } else {
2372        console.log(arg.foo)    // Compile-time error
2373        console.log(arg.bar)    // OK
2374    }
2375}
2376
2377doStuff({ foo: 123, common: '123' })
2378doStuff({ bar: 123, common: '123' })
2379```
2380
2381**ArkTS**
2382
2383```typescript
2384class Foo {
2385    foo: number = 0
2386    common: string = ""
2387}
2388
2389class Bar {
2390    bar: number = 0
2391    common: string = ""
2392}
2393
2394function isFoo(arg: Object): boolean {
2395    return arg instanceof Foo
2396}
2397
2398function doStuff(arg: Object): void {
2399    if (isFoo(arg)) {
2400        let fooArg = arg as Foo
2401        console.log(fooArg.foo)     // OK
2402        console.log(arg.bar)        // Compile-time error
2403    } else {
2404        let barArg = arg as Bar
2405        console.log(arg.foo)        // Compile-time error
2406        console.log(barArg.bar)     // OK
2407    }
2408}
2409
2410function main(): void {
2411    doStuff(new Foo())
2412    doStuff(new Bar())
2413}
2414```
2415
2416### Recipe: It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals
2417
2418**Rule:** `arkts-no-spread`
2419
2420**Severity: error**
2421
2422The only supported scenario for the spread operator is to spread an array or
2423class derived from array into the rest parameter or array literal.
2424Otherwise, manually "unpack" data from arrays and objects, where necessary.
2425All typed arrays from the standard library (for example, ``Int32Array``)
2426are also supported.
2427
2428**TypeScript**
2429
2430```typescript
2431function foo(x : number, y : number, z : number) {
2432    console.log(x, y, z)
2433}
2434
2435let args : [number, number, number] = [0, 1, 2]
2436foo(...args)
2437
2438let list1 = [1, 2]
2439let list2 = [...list1, 3, 4]
2440
2441let point2d = {x: 1, y: 2}
2442let point3d = {...point2d, z: 3}
2443```
2444
2445**ArkTS**
2446
2447```typescript
2448function sum_numbers(...numbers: number[]): number {
2449    let res = 0
2450    for (let n of numbers)
2451        res += n
2452    return res
2453}
2454console.log(sum_numbers(1, 2, 3))
2455
2456function log_numbers(x : number, y : number, z : number) {
2457    console.log(x, y, z)
2458}
2459let numbers: number[] = [1, 2, 3]
2460log_numbers(numbers[0], numbers[1], numbers[2])
2461
2462let list1 : number[] = [1, 2]
2463let list2 : number[] = [list1[0], list1[1], 3, 4]
2464
2465class Point2D {
2466    x: number = 0; y: number = 0
2467}
2468
2469class Point3D {
2470    x: number = 0; y: number = 0; z: number = 0
2471    constructor(p2d: Point2D, z: number) {
2472        this.x = p2d.x
2473        this.y = p2d.y
2474        this.z = z
2475    }
2476}
2477
2478let p3d = new Point3D({x: 1, y: 2} as Point2D, 3)
2479console.log(p3d.x, p3d.y, p3d.z)
2480
2481class DerivedFromArray extends Uint16Array {};
2482
2483let arr1 = [1, 2, 3];
2484let arr2 = new Uint16Array([4, 5, 6]);
2485let arr3 = new DerivedFromArray([7, 8, 9])
2486let arr4 = [...arr1, 10, ...arr2, 11, ...arr3]
2487```
2488
2489### Recipe: Interface Cannot Extend Interfaces with the Same Method
2490
2491**Rule:** `arkts-no-extend-same-prop`
2492
2493**Severity: error**
2494
2495In TypeScript, an interface that extends two other interfaces with the same method
2496must declare that method with a combined return type. It is not allowed in
2497ArkTS because ArkTS does not allow an interface to contain two methods with
2498signatures that are not distinguishable, for example, two methods that have the same
2499parameter lists but different return types.
2500
2501**TypeScript**
2502
2503```typescript
2504interface Mover {
2505    getStatus(): { speed: number }
2506}
2507interface Shaker {
2508    getStatus(): { frequency: number }
2509}
2510
2511interface MoverShaker extends Mover, Shaker {
2512    getStatus(): {
2513        speed: number
2514        frequency: number
2515    }
2516}
2517
2518class C implements MoverShaker {
2519    private speed: number = 0
2520    private frequency: number = 0
2521
2522    getStatus() {
2523        return { speed: this.speed, frequency: this.frequency }
2524    }
2525}
2526```
2527
2528**ArkTS**
2529
2530```typescript
2531class MoveStatus {
2532    public speed : number
2533    constructor() {
2534        this.speed = 0
2535    }
2536}
2537interface Mover {
2538    getMoveStatus(): MoveStatus
2539}
2540
2541class ShakeStatus {
2542    public frequency : number
2543    constructor() {
2544        this.frequency = 0
2545    }
2546}
2547interface Shaker {
2548    getShakeStatus(): ShakeStatus
2549}
2550
2551class MoveAndShakeStatus {
2552    public speed : number
2553    public frequency : number
2554    constructor() {
2555        this.speed = 0
2556        this.frequency = 0
2557    }
2558}
2559
2560class C implements Mover, Shaker {
2561    private move_status : MoveStatus
2562    private shake_status : ShakeStatus
2563
2564    constructor() {
2565        this.move_status = new MoveStatus()
2566        this.shake_status = new ShakeStatus()
2567    }
2568
2569    public getMoveStatus() : MoveStatus {
2570        return this.move_status
2571    }
2572
2573    public getShakeStatus() : ShakeStatus {
2574        return this.shake_status
2575    }
2576
2577    public getStatus(): MoveAndShakeStatus {
2578        return {
2579            speed: this.move_status.speed,
2580            frequency: this.shake_status.frequency
2581        }
2582    }
2583}
2584```
2585
2586### Recipe: Declaration Merging Is Not Supported
2587
2588**Rule:** `arkts-no-decl-merging`
2589
2590**Severity: error**
2591
2592ArkTS does not support merging declarations. Keep all definitions of classes
2593and interfaces compact in the codebase.
2594
2595**TypeScript**
2596
2597```typescript
2598interface Document {
2599    createElement(tagName: any): Element
2600}
2601
2602interface Document {
2603    createElement(tagName: string): HTMLElement
2604}
2605
2606interface Document {
2607    createElement(tagName: number): HTMLDivElement
2608    createElement(tagName: boolean): HTMLSpanElement
2609    createElement(tagName: string, value: number): HTMLCanvasElement
2610}
2611```
2612
2613**ArkTS**
2614
2615```typescript
2616interface Document {
2617    createElement(tagName: number): HTMLDivElement
2618    createElement(tagName: boolean): HTMLSpanElement
2619    createElement(tagName: string, value: number): HTMLCanvasElement
2620    createElement(tagName: string): HTMLElement
2621    createElement(tagName: Object): Element
2622}
2623```
2624
2625### Recipe: Interfaces Cannot Extend Classes
2626
2627**Rule:** `arkts-extends-only-class`
2628
2629**Severity: error**
2630
2631ArkTS does not support interfaces that extend classes. Interfaces can extend
2632only interfaces.
2633
2634**TypeScript**
2635
2636```typescript
2637class Control {
2638    state: number = 0
2639}
2640
2641interface SelectableControl extends Control {
2642    select(): void
2643}
2644```
2645
2646**ArkTS**
2647
2648```typescript
2649interface Control {
2650    state: number
2651}
2652
2653interface SelectableControl extends Control {
2654    select(): void
2655}
2656```
2657
2658### Recipe: Constructor Function Type Is Not Supported
2659
2660**Rule:** `arkts-no-ctor-signatures-funcs`
2661
2662**Severity: error**
2663
2664ArkTS does not support the usage of the constructor function type.
2665Use lambdas instead.
2666
2667**TypeScript**
2668
2669```typescript
2670class Person {
2671    constructor(
2672        name: string,
2673        age: number
2674    ) {}
2675}
2676type PersonCtor = new (name: string, age: number) => Person
2677
2678function createPerson(Ctor: PersonCtor, name: string, age: number): Person
2679{
2680    return new Ctor(name, age)
2681}
2682
2683const person = createPerson(Person, 'John', 30)
2684```
2685
2686**ArkTS**
2687
2688```typescript
2689class Person {
2690    constructor(
2691        name: string,
2692        age: number
2693    ) {}
2694}
2695type PersonCtor = (n: string, a: number) => Person
2696
2697function createPerson(Ctor: PersonCtor, n: string, a: number): Person {
2698    return Ctor(n, a)
2699}
2700
2701let Impersonizer: PersonCtor = (n: string, a: number): Person => {
2702    return new Person(n, a)
2703}
2704
2705const person = createPerson(Impersonizer, "John", 30)
2706```
2707
2708### Recipe: Enumeration Members Can Be Initialized Only with Compile Time Expressions of the Same Type
2709
2710**Rule:** `arkts-no-enum-mixed-types`
2711
2712**Severity: error**
2713
2714ArkTS does not support initializing members of enumerations with expressions
2715that are evaluated during program runtime. Besides, all explicitly set
2716initializers must be of the same type.
2717
2718**TypeScript**
2719
2720```typescript
2721enum E1 {
2722    A = 0xa,
2723    B = 0xb,
2724    C = Math.random(),
2725    D = 0xd,
2726    E // 0xe inferred
2727}
2728
2729enum E2 {
2730    A = 0xa,
2731    B = "0xb",
2732    C = 0xc,
2733    D = "0xd"
2734}
2735```
2736
2737**ArkTS**
2738
2739```typescript
2740enum E1 {
2741    A = 0xa,
2742    B = 0xb,
2743    C = 0xc,
2744    D = 0xd,
2745    E // 0xe inferred
2746}
2747
2748enum E2 {
2749    A = "0xa",
2750    B = "0xb",
2751    C = "0xc",
2752    D = "0xd"
2753}
2754```
2755
2756### Recipe: `enum` Declaration Merging Is Not Supported
2757
2758**Rule:** `arkts-no-enum-merging`
2759
2760**Severity: error**
2761
2762ArkTS does not support merging declarations for `enum`. Keep the
2763declaration of each `enum` compact in the codebase.
2764
2765**TypeScript**
2766
2767```typescript
2768enum Color {
2769    RED,
2770    GREEN
2771}
2772enum Color {
2773    YELLOW = 2
2774}
2775enum Color {
2776    BLACK = 3,
2777    BLUE
2778}
2779```
2780
2781**ArkTS**
2782
2783```typescript
2784enum Color {
2785    RED,
2786    GREEN,
2787    YELLOW,
2788    BLACK,
2789    BLUE
2790}
2791```
2792
2793### Recipe: Namespaces Cannot Be Used as Objects
2794
2795**Rule:** `arkts-no-ns-as-obj`
2796
2797**Severity: error**
2798
2799ArkTS does not support the usage of namespaces as objects.
2800Classes or modules can be interpreted as analogs of namespaces.
2801
2802**TypeScript**
2803
2804```typescript
2805namespace MyNamespace {
2806    export let x: number
2807}
2808
2809let m = MyNamespace
2810m.x = 2
2811```
2812
2813**ArkTS**
2814
2815```typescript
2816namespace MyNamespace {
2817    export let x: number
2818}
2819
2820MyNamespace.x = 2
2821```
2822
2823### Recipe: Non-declaration Statements in Namespaces Are Not Supported
2824
2825**Rule:** `arkts-no-ns-statements`
2826
2827**Severity: error**
2828
2829ArkTS does not support statements in namespaces. Use a function to execute
2830statements.
2831
2832**TypeScript**
2833
2834```typescript
2835namespace A {
2836    export let x: number
2837    x = 1
2838}
2839```
2840
2841**ArkTS**
2842
2843```typescript
2844namespace A {
2845    export let x: number
2846
2847    export function init() {
2848      x = 1
2849    }
2850}
2851
2852// Initialization function should be called to execute statements.
2853A.init()
2854```
2855
2856### Recipe: Special `import type` Declarations Are Not Supported
2857
2858**Rule:** `arkts-no-special-imports`
2859
2860**Severity: error**
2861
2862ArkTS does not have a special notation for import types.
2863Use the ordinary `import` syntax instead.
2864
2865**TypeScript**
2866
2867```typescript
2868// Re-using the same import.
2869import { APIResponseType } from "api"
2870
2871// Explicitly use the import type.
2872import type { APIResponseType } from "api"
2873```
2874
2875**ArkTS**
2876
2877```typescript
2878import { APIResponseType } from "api"
2879```
2880
2881**See also**
2882
2883* Recipe: Importing a Module for Side-Effects Only Is Not Supported
2884* Recipe: `import default as ...` Is Not Supported
2885* Recipe: `require` and `import` Assignment Are Not Supported
2886
2887### Recipe: Importing a Module for Side-Effects Only Is Not Supported
2888
2889**Rule:** `arkts-no-side-effects-imports`
2890
2891**Severity: error**
2892
2893ArkTS does not support global variables like `window` to avoid
2894side-effects during module importing. All variables marked as export can be
2895accessed through the `*` syntax.
2896
2897**TypeScript**
2898
2899```typescript
2900// === module at "path/to/module.ts"
2901export const EXAMPLE_VALUE = 42
2902
2903// Set a global variable.
2904window.MY_GLOBAL_VAR = "Hello, world!"
2905
2906// ==== using this module:
2907import "path/to/module"
2908```
2909
2910**ArkTS**
2911
2912```typescript
2913import * as m from "path/to/module"
2914```
2915
2916### Recipe: `import default as ...` Is Not Supported
2917
2918**Rule:** `arkts-no-import-default-as`
2919
2920**Severity: error**
2921
2922ArkTS does not support the `import default as ...` syntax.
2923Use explicit `import ... from ...` instead.
2924
2925**TypeScript**
2926
2927```typescript
2928import { default as d } from "mod"
2929```
2930
2931**ArkTS**
2932
2933```typescript
2934import d from "mod"
2935```
2936
2937### Recipe: `require` and `import` Assignment Are Not Supported
2938
2939**Rule:** `arkts-no-require`
2940
2941**Severity: error**
2942
2943ArkTS does not support importing via `require`.
2944It does not support `import` assignments either.
2945Use the regular `import` syntax  instead.
2946
2947**TypeScript**
2948
2949```typescript
2950import m = require("mod")
2951```
2952
2953**ArkTS**
2954
2955```typescript
2956import * as m from "mod"
2957```
2958
2959**See also**
2960
2961* Recipe: `export = ...` Is Not Supported
2962
2963### Recipe: `export = ...` Is Not Supported
2964
2965**Rule:** `arkts-no-export-assignment`
2966
2967**Severity: error**
2968
2969ArkTS does not support the `export = ...` syntax.
2970Use the ordinary `export` and `import` syntaxes instead.
2971
2972**TypeScript**
2973
2974```typescript
2975// module1
2976export = Point
2977
2978class Point {
2979    constructor(x: number, y: number) {}
2980    static origin = new Point(0, 0)
2981}
2982
2983// module2
2984import Pt = require("module1")
2985
2986let p = Pt.Point.origin
2987```
2988
2989**ArkTS**
2990
2991```typescript
2992// module1
2993export class Point {
2994    constructor(x: number, y: number) {}
2995    static origin = new Point(0, 0)
2996}
2997
2998// module2
2999import * as Pt from "module1"
3000
3001let p = Pt.Point.origin
3002```
3003
3004**See also**
3005
3006* Recipe: `require` and `import` Assignment Are Not Supported
3007
3008### Recipe: Special `export type` Declarations Are Not Supported
3009
3010**Rule:** `arkts-no-special-exports`
3011
3012**Severity: error**
3013
3014ArkTS does not have a special notation for exporting types through
3015`export type ...`. Use the ordinary `export`syntax  instead.
3016
3017**TypeScript**
3018
3019```typescript
3020// Explicitly exported class:
3021export class Class1 {
3022    // ...
3023}
3024
3025// Declared class later exported through the export type ...
3026class Class2 {
3027    // ...
3028}
3029
3030// This is not supported.
3031export type { Class2 }
3032```
3033
3034**ArkTS**
3035
3036```typescript
3037// Explicitly exported class:
3038export class Class1 {
3039    // ...
3040}
3041
3042// Explicitly exported class:
3043export class Class2 {
3044    // ...
3045}
3046```
3047
3048### Recipe: Ambient Module Declaration Is Not Supported
3049
3050**Rule:** `arkts-no-ambient-decls`
3051
3052**Severity: error**
3053
3054ArkTS does not support ambient module declaration because it has its
3055own mechanisms for interoperating with JavaScript.
3056
3057**TypeScript**
3058
3059```typescript
3060declare module "someModule" {
3061    export function normalize(s : string) : string;
3062}
3063```
3064
3065**ArkTS**
3066
3067```typescript
3068// Import what you need from the original module.
3069import { normalize } from "someModule"
3070```
3071
3072**See also**
3073
3074* Recipe: Wildcards in Module Names Are Not Supported
3075
3076### Recipe: Wildcards in Module Names Are Not Supported
3077
3078**Rule:** `arkts-no-module-wildcards`
3079
3080**Severity: error**
3081
3082ArkTS does not support wildcards in module names, because
3083import is a compile-time feature in ArkTS, not a runtime feature.
3084Use the ordinary `export` syntax instead.
3085
3086**TypeScript**
3087
3088```typescript
3089// Declaration:
3090declare module "*!text" {
3091    const content: string
3092    export default content
3093}
3094
3095// Consuming code:
3096import fileContent from "some.txt!text"
3097```
3098
3099**ArkTS**
3100
3101```typescript
3102// Declaration:
3103declare namespace N {
3104    function foo(x: number): number
3105}
3106
3107// Consuming code:
3108import * as m from "module"
3109console.log("N.foo called: ", N.foo(42))
3110```
3111
3112**See also**
3113
3114* Recipe: Ambient Module Declaration Is Not Supported
3115* Recipe: UMD Is Not Supported
3116
3117### Recipe: UMD Is Not Supported
3118
3119**Rule:** `arkts-no-umd`
3120
3121**Severity: error**
3122
3123ArkTS does not support universal module definitions (UMD), because it does not have the concept of "script" (as opposed to "module").
3124In addition, import is a compile-time feature in ArkTS, not a runtime feature.
3125Use the ordinary `export` and `import` syntaxes instead.
3126
3127**TypeScript**
3128
3129```typescript
3130// math-lib.d.ts
3131export const isPrime(x: number): boolean
3132export as namespace mathLib
3133
3134// In script
3135mathLib.isPrime(2)
3136```
3137
3138**ArkTS**
3139
3140```typescript
3141// math-lib.d.ts
3142namespace mathLib {
3143    export isPrime(x: number): boolean
3144}
3145
3146// In program
3147import { mathLib } from "math-lib"
3148mathLib.isPrime(2)
3149```
3150
3151**See also**
3152
3153* Recipe: Wildcards in Module Names Are Not Supported
3154
3155### Recipe: `new.target` Is Not Supported
3156
3157**Rule:** `arkts-no-new-target`
3158
3159**Severity: error**
3160
3161ArkTS does not support `new.target`, because there is no concept of runtime
3162prototype inheritance in the language. This feature is considered not applicable
3163to static typing.
3164
3165**TypeScript**
3166
3167```typescript
3168class CustomError extends Error {
3169    constructor(message?: string) {
3170        // 'Error' breaks the prototype chain here.
3171        super(message)
3172
3173        // Restore the prototype chain.
3174        Object.setPrototypeOf(this, new.target.prototype)
3175    }
3176}
3177```
3178
3179**ArkTS**
3180
3181```typescript
3182class CustomError extends Error {
3183    constructor(message?: string) {
3184        // Call parent's constructor, inheritance chain is static and
3185        // cannot be modified in runtime
3186        super(message)
3187        console.log(this instanceof Error) // true
3188    }
3189}
3190let ce = new CustomError()
3191```
3192
3193**See also**
3194
3195* Recipe: Prototype Assignment Is Not Allowed
3196
3197### Recipe: Definite Assignment Assertions Are Not Supported
3198
3199**Rule:** `arkts-no-definite-assignment`
3200
3201**Severity: warning**
3202
3203ArkTS does not support definite assignment assertions `let v!: T` because
3204they are considered an excessive compiler hint.
3205Use declarations with initialization instead.
3206
3207**TypeScript**
3208
3209```typescript
3210let x!: number // Hint: x will be initialized before usage.
3211
3212initialize()
3213
3214function initialize() {
3215    x = 10
3216}
3217
3218console.log("x = " + x)
3219```
3220
3221**ArkTS**
3222
3223```typescript
3224function initialize() : number {
3225    return 10
3226}
3227
3228let x: number = initialize()
3229
3230console.log("x = " + x)
3231```
3232
3233### Recipe: Prototype Assignment Is Not Supported
3234
3235**Rule:** `arkts-no-prototype-assignment`
3236
3237**Severity: error**
3238
3239ArkTS does not support prototype assignment because there is no concept of
3240runtime prototype inheritance in the language. This feature is considered not
3241applicable to static typing. Mechanism of classes and/or interfaces must
3242be used instead to statically "combine" methods to data together.
3243
3244**TypeScript**
3245
3246```typescript
3247var C = function(p: number) {
3248    this.p = p // Compile-time error only when noImplicitThis is enabled
3249}
3250
3251C.prototype = {
3252    m() {
3253        console.log(this.p)
3254    }
3255}
3256
3257C.prototype.q = function(r: number) {
3258    return this.p == r
3259}
3260```
3261
3262**ArkTS**
3263
3264```typescript
3265class C {
3266    p: number = 0
3267    m() {
3268        console.log(this.p)
3269    }
3270    q(r: number) {
3271        return this.p == r
3272    }
3273}
3274```
3275
3276**See also**
3277
3278* Recipe: new.target Is Not Supported
3279
3280### Recipe: `globalThis` Is Not Supported
3281
3282**Rule:** `arkts-no-globalthis`
3283
3284**Severity: error**
3285
3286ArkTS does not support both global scope and `globalThis` because untyped
3287objects with dynamically changed layout are not supported.
3288
3289**TypeScript**
3290
3291```typescript
3292// In a global file:
3293var abc = 100
3294
3295// Refers to 'abc' from above.
3296globalThis.abc = 200
3297```
3298
3299**ArkTS**
3300
3301```typescript
3302// File 1
3303export let abc : number = 0
3304
3305// File 2
3306import * as M from "file1"
3307
3308M.abc = 200
3309```
3310
3311**See also**
3312
3313* Recipe: Declaring Properties on Functions Is Not Supported
3314* Recipe: Usage of Standard Libraries Is Restricted
3315
3316### Recipe: Some Utility Types Are Not Supported
3317
3318**Rule:** `arkts-no-utility-types`
3319
3320**Severity: error**
3321
3322Currently ArkTS does not support utility types from TypeScript extensions to the
3323standard library. Exceptions are `Partial`, `Required`, `Readonly` and `Record`.
3324
3325For the type *Record<K, V>*, the type of an indexing expression *rec[index]* is
3326of the type *V | undefined*.
3327
3328### Recipe: Declaring Properties on Functions Is Not Supported
3329
3330**Rule:** `arkts-no-func-props`
3331
3332**Severity: error**
3333
3334ArkTS does not support declaring properties on functions because there is no
3335support for objects with dynamically changing layout. Function objects follow
3336this rule and their layout cannot be changed at runtime.
3337
3338**TypeScript**
3339
3340```typescript
3341class MyImage {
3342    // ...
3343}
3344
3345function readImage(
3346    path: string, callback: (err: any, image: MyImage) => void
3347)
3348{
3349    // ...
3350}
3351
3352function readFileSync(path : string) : number[] {
3353    return []
3354}
3355
3356function decodeImageSync(contents : number[]) {
3357    // ...
3358}
3359
3360readImage.sync = (path: string) => {
3361    const contents = readFileSync(path)
3362    return decodeImageSync(contents)
3363}
3364```
3365
3366**ArkTS**
3367
3368```typescript
3369class MyImage {
3370    // ...
3371}
3372
3373async function readImage(
3374    path: string, callback: (err: Error, image: MyImage) => void
3375) : Promise<MyImage>
3376{
3377    // In real world, the implementation is more complex,
3378    // involving real network / DB logic, etc.
3379    return await new MyImage()
3380}
3381
3382function readImageSync(path: string) : MyImage {
3383    return new MyImage()
3384}
3385```
3386
3387**See also**
3388
3389* Recipe: `globalThis` Is Not Supported
3390
3391### Recipe: `Function.apply`, `Function.bind`, and `Function.call` Are Not Supported
3392
3393**Rule:** `arkts-no-func-apply-bind-call`
3394
3395**Severity: error**
3396
3397ArkTS does not support `Function.apply`, `Function.bind`, or `Function.call`. These APIs are needed in the standard
3398library to explicitly set the parameter `this` for the called function.
3399In ArkTS, the semantics of `this` is restricted to the conventional OOP
3400style, and the usage of `this` in stand-alone functions is prohibited.
3401
3402**See also**
3403
3404* Recipe: Using `this` Inside Stand-Alone Functions Is Not Supported
3405
3406### Recipe: `as const` Assertions Are Not Supported
3407
3408**Rule:** `arkts-no-as-const`
3409
3410**Severity: error**
3411
3412ArkTS does not support `as const` assertions, because in standard TypeScript
3413`as const` is used to annotate literals with corresponding literal types, and ArkTS
3414does not support literal types.
3415
3416**TypeScript**
3417
3418```typescript
3419// Type 'hello':
3420let x = "hello" as const
3421
3422// Type 'readonly [10, 20]':
3423let y = [10, 20] as const
3424
3425// Type '{ readonly text: "hello" }':
3426let z = { text: "hello" } as const
3427```
3428
3429**ArkTS**
3430
3431```typescript
3432// Type 'string':
3433let x : string = "hello"
3434
3435// Type 'number[]':
3436let y : number[] = [10, 20]
3437
3438class Label {
3439    text : string = ""
3440}
3441
3442// Type 'Label':
3443let z : Label = {
3444    text: "hello"
3445}
3446```
3447
3448### Recipe: Import Assertions Are Not Supported
3449
3450**Rule:** `arkts-no-import-assertions`
3451
3452**Severity: error**
3453
3454ArkTS does not support import assertions, because import is a
3455compile-time feature in ArkTS, not a runtime feature. So asserting the correctness of imported APIs
3456in runtime does not make sense for the statically typed language. Use the ordinary
3457`import` syntax instead.
3458
3459**TypeScript**
3460
3461```typescript
3462import { obj } from "something.json" assert { type: "json" }
3463```
3464
3465**ArkTS**
3466
3467```typescript
3468// The correctness of importing T will be checked at compile time.
3469import { something } from "module"
3470```
3471
3472**See also**
3473
3474* Recipe: Ambient Module Declaration Is Not Supported
3475* Recipe: UMD Is Not Supported
3476
3477### Recipe: Usage of Standard Libraries Is Restricted
3478
3479**Rule:** `arkts-limited-stdlib`
3480
3481**Severity: error**
3482
3483ArkTS does not support certain APIs in the TypeScript and JavaScript standard libraries.
3484Most of these restricted APIs are used to manipulate objects in a
3485dynamic manner, which is not compatible with static typing. The usage of
3486the following APIs is prohibited:
3487
3488Properties and functions of the global object: `eval`,
3489`Infinity`, `NaN`, `isFinite`, `isNaN`, `parseFloat`, `parseInt`,
3490`Encode`, `Decode`, `ParseHexOctet`
3491
3492`Object`: `__proto__`, `__defineGetter__`, `__defineSetter__`,
3493`__lookupGetter__`, `__lookupSetter__`, `assign`, `create`,
3494`defineProperties`, `defineProperty`, `freeze`,
3495`fromEntries`, `getOwnPropertyDescriptor`, `getOwnPropertyDescriptors`,
3496`getOwnPropertySymbols`, `getPrototypeOf`,
3497`hasOwnProperty`, `is`, `isExtensible`, `isFrozen`,
3498`isPrototypeOf`, `isSealed`, `preventExtensions`,
3499`propertyIsEnumerable`, `seal`, `setPrototypeOf`
3500
3501`Reflect`: `apply`, `construct`, `defineProperty`, `deleteProperty`,
3502`getOwnPropertyDescriptor`, `getPrototypeOf`,
3503`isExtensible`, `preventExtensions`,
3504`setPrototypeOf`
3505
3506`Proxy`: `handler.apply()`, `handler.construct()`,
3507`handler.defineProperty()`, `handler.deleteProperty()`, `handler.get()`,
3508`handler.getOwnPropertyDescriptor()`, `handler.getPrototypeOf()`,
3509`handler.has()`, `handler.isExtensible()`, `handler.ownKeys()`,
3510`handler.preventExtensions()`, `handler.set()`, `handler.setPrototypeOf()`
3511
3512`ArrayBuffer`: `isView`
3513
3514**See also**
3515
3516* Recipe: Objects with Property Names That Are Not Identifiers Are Not Supported
3517* Recipe: `Symbol()` Is Not Supported
3518* Recipe: Indexed Access Is Not Supported for Fields
3519* Recipe: `typeof` Operator Is Allowed Only in Expression Contexts
3520* Recipe: `in` Operator Is Not Supported
3521* Recipe: `globalThis` Is Not Supported
3522
3523### Recipe: Strict Type Checking Is Enforced
3524
3525**Rule:** `arkts-strict-typing`
3526
3527**Severity: error**
3528
3529Type checking in ArkTS is not optional. Any code must be explicitly and
3530correctly typed to be compiled and run. When porting code from standard TypeScript,
3531enable the following flags: `noImplicitReturns`, `strictFunctionTypes`,
3532`strictNullChecks`, and `strictPropertyInitialization`.
3533
3534**TypeScript**
3535
3536```typescript
3537class C {
3538    n: number // Compile-time error only when strictPropertyInitialization is enabled.
3539    s: string // Compile-time error only when strictPropertyInitialization is enabled.
3540}
3541
3542// Compile-time error only when noImplicitReturns is enabled.
3543function foo(s: string): string {
3544    if (s != "") {
3545        console.log(s)
3546        return s
3547    } else {
3548        console.log(s)
3549    }
3550}
3551
3552let n: number = null // Compile-time error only when strictNullChecks is enabled.
3553```
3554
3555**ArkTS**
3556
3557```typescript
3558class C {
3559    n: number = 0
3560    s: string = ""
3561}
3562
3563function foo(s: string): string {
3564    console.log(s)
3565    return s
3566}
3567
3568let n1: number | null = null
3569let n2: number = 0
3570```
3571
3572**See also**
3573
3574* Recipe: Use Explicit Types Instead of `any` or `unknown`
3575* Recipe: Disabling Type Checking with In-Place Comments Is Not Allowed
3576
3577### Recipe: Disabling Type Checking with In-Place Comments Is Not Allowed
3578
3579**Rule:** `arkts-strict-typing-required`
3580
3581**Severity: error**
3582
3583Type checking in ArkTS is not optional. Any code must be explicitly and
3584correctly typed to be compiled and run. Disabling type checking in-place
3585with special comments is not allowed. In particular, `@ts-ignore` and
3586`@ts-nocheck` annotations are not supported.
3587
3588**TypeScript**
3589
3590```typescript
3591// @ts-nocheck
3592// ...
3593// Some code with type checking disabled.
3594// ...
3595
3596let s1: string = null // No error, since type checking is disabled.
3597
3598// @ts-ignore
3599let s2: string = null // No error, since type checking is disabled.
3600```
3601
3602**ArkTS**
3603
3604```typescript
3605let s1: string | null = null // No error. The types are proper.
3606let s2: string = null // Compile-time error.
3607```
3608
3609**See also**
3610
3611* Recipe: Use Explicit Types Instead of any or unknown
3612* Recipe: Strict Type Checking Is Enforced
3613
3614### Recipe: No Dependencies on TypeScript Code Are Allowed
3615
3616**Rule:** `arkts-no-ts-deps`
3617
3618**Severity: error**
3619
3620Currently, the codebase implemented in the standard TypeScript language must not
3621depend on ArkTS by importing an ArkTS codebase. Imports in the reverse
3622direction are supported.
3623
3624**TypeScript**
3625
3626```typescript
3627// app.ets
3628export class C {
3629    // ...
3630}
3631
3632// lib.ts
3633import { C } from "app"
3634```
3635
3636**ArkTS**
3637
3638```typescript
3639// lib1.ets
3640export class C {
3641    // ...
3642}
3643
3644// lib2.ets
3645import { C } from "lib1"
3646```
3647
3648### Recipe: Only ArkUI Decorators Are Allowed
3649
3650**Rule:** `arkts-no-decorators-except-arkui`
3651
3652**Severity: warning**
3653
3654Currently, only ArkUI decorators are allowed in ArkTS.
3655Any other decorator will cause a compile-time error.
3656
3657**TypeScript**
3658
3659```typescript
3660function classDecorator(x: any, y: any): void {
3661    //
3662}
3663
3664@classDecorator
3665class BugReport {
3666}
3667```
3668
3669**ArkTS**
3670
3671```typescript
3672function classDecorator(x: any, y: any): void {
3673    //
3674}
3675
3676@classDecorator // Compile-time error: unsupported decorators.
3677class BugReport {
3678}
3679```
3680
3681### Recipe: Classes Cannot Be Used as Objects
3682
3683**Rule:** `arkts-no-classes-as-obj`
3684
3685**Severity: error**
3686
3687ArkTS does not support using classes as objects (assigning them to variables,
3688etc.). This is because in ArkTS, a `class` declaration introduces a new type,
3689not a value.
3690
3691**TypeScript**
3692
3693```typescript
3694class C {
3695    s: string = ""
3696    n: number = 0
3697}
3698
3699let c = C
3700```
3701
3702### Recipe: `import` Statements After Other Statements Are Not Allowed
3703
3704**Rule:** `arkts-no-misplaced-imports`
3705
3706**Severity: error**
3707
3708In ArkTS, all `import` statements should go before all other statements
3709in the program.
3710
3711**TypeScript**
3712
3713```typescript
3714class C {
3715    s: string = ""
3716    n: number = 0
3717}
3718
3719import foo from "module1"
3720```
3721
3722**ArkTS**
3723
3724```typescript
3725import foo from "module1"
3726
3727class C {
3728    s: string = ""
3729    n: number = 0
3730}
3731```
3732