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