1# ArkCompiler Subsystem Changelog
2
3## cl.ArkCompiler.1 TypeScript Syntax Check Change
4
5**Access Level**
6Other
7
8**Reason for Change**
9The TypeScript version in the OpenHarmony SDK is upgraded from 4.2.3 to 4.9.5. The new version supports more syntax features and provides higher type check capabilities. However, there are a few syntax features that are incompatible with earlier versions.
10
11**Change Occurrence Version**
12OpenHarmony SDK 4.1.3.1
13
14**Change Impact**
15Compared with earlier versions, the syntax check in the new TypeScript version is stricter. It has 10 types of syntax features that are incompatible with the existing syntax. The following describes these syntax features and provides simple examples.
16
17**Changed Syntax Features and Adaptation Guide**
18
191. Union enums cannot be compared to arbitrary numbers.
20Enums are considered union enums when their members are either automatically filled in, or trivially written. An enum of this type can recall each value that it potentially represents.
21The following is an incorrect example:
22
23    ```
24    enum E {
25      A = 0,
26      B = 1,
27    }
28    function doSomething(x: E) {
29      // Error! This condition will always return 'false' since the types 'E' and '-1' have no overlap.
30      if (x === -1) {
31        // ...
32      }
33    }
34    ```
35    Adaptation suggestion: Use the **toString()** method to convert a number into a string for comparison.
36
372. More compliant indirect calls to imported functions.
38   When an import from a non-ES module (such as the commonjs module in the FA model) is called, the **this** value is discarded, just as when an import from an ES module is called.
39   The following example shows the change:
40   ```
41    // Assume that this is the imported module, which has a 'foo' and 'feature' export.
42    let fooModule = {
43      foo() {
44        console.log(this);
45      },
46      feature: 'oh'
47    };
48
49    // Behavior before the change:
50    fooModule.foo(); // Output: {"feature": "oh"}
51
52    // Behavior after the change (in effect, '(0, fooModule.foo) is called, which is slightly different from the preceding behavior):
53    (0, fooModule.foo)(); // Output: undefined
54   ```
553. Abstract properties do not allow initializers.
56The following code will report an error because abstract properties are not allowed have initializers:
57    ```
58    abstract class C {
59      abstract prop = 1;
60      //       ~~~~
61      // Property 'prop' cannot have an initializer because it is marked abstract.
62    }
63    ```
64    Adaptation suggestion: Delete the initializer.
654. The rest parameter syntax deletes unexpandable members from generic objects.
66When being deconstructed from generic objects, properties are regarded as all deconstructible in earlier versions. In the new version, they are strictly analyzed to find out whether they can be deconstructed. Properties that should not be deconstructed include private properties, private methods, and static properties. The following code will report an error:
67    ```
68    class Thing {
69      someProperty = 42;
70      someMethod() {
71        // ...
72      }
73    }
74    function foo<T extends Thing>(x: T) {
75      let { someProperty, ...rest } = x;
76      // Used to work, is now an error!
77      // Property 'someMethod' does not exist on type 'Omit<T, "someProperty" | "someMethod">'.
78      rest.someMethod();
79    }
80    ```
81    Adaptation suggestion: When deconstructing a property from a generic object, make sure it can be deconstructed.
825. There are stricter checks with template string expressions.
83If a symbol value is used in JavaScript, both JavaScript and TypeScript will throw an error. However, TypeScript now checks whether a generic value contained in a symbol is used in the template string.
84    ```
85    function logKey<S extends string | symbol>(key: S): S {
86        // Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.
87        console.log(`${key} is the key`);
88        return key;
89    }
90    ```
91    Adaptation suggestion: Wrap the expression in **'String(...)'**.
926. Read-only tuples have a read-only length property.
93    The read-only tuple now treats the length property as read-only. This can be seen for tuples with optional trailing and rest element types.
94    ```
95    function overwriteLength(tuple: readonly [string, string, string]) {
96        // Now errors.
97        tuple.length = 7;
98    }
99    ```
1007. Objects cannot be compared with array literals.
101Value-comparison operations '==' and '===' between objects (and arrays) in JavaScript check whether two references point to the same value. Now the following code will report an error:
102    ```
103    if (peopleAtHome === []) {
104    //  ~~~~~~~~~~~~~~~~~~~
105    // This condition will always return 'false' since JavaScript compares objects by reference, not value.
106        console.log("here's where I lie, broken inside. </3")
107        adoptAnimals();
108    }
109    ```
1108. Unused renames are not allowed in type signatures.
111In the following example, you might think that **makePerson** takes an object with a **name** property of the string type and an **age** property of the number type. However, the destructuring syntax is actually taking precedence here. **makePerson** renames **name** and **age** to **string** and **number** respectively.
112    ```
113    declare function makePerson({ name: string, age: number }): Person;
114    ```
115    The correct way to write the above signature is as follows:
116    ```
117    declare function makePerson(options: { name: string, age: number }): Person;
118    // or
119    declare function makePerson({ name, age }: { name: string, age: number }): Person;
120    ```
1219. Checks for equality on NaN.
122An error will be reported on direct comparisons against NaN.
123    ```
124    function validate(someValue: number) {
125        return someValue !== NaN;
126        //     ~~~~~~~~~~~~~~~~~
127        // error: This condition will always return 'true'. Did you mean '!Number.isNaN(someValue)'?
128    }
129    ```
130    Adaptation suggestion: Use **Number.isNaN** instead.
13110. Errors caused by enhanced type inference and check capabilities
132After TypeScript is upgraded to 4.9.5, its type inference and check capabilities are enhanced, and syntax errors other than those described above may be detected. Correcting these syntax errors help improve run-time performance.
133