1# ArkCompiler子系统Changelog
2
3## cl.ArkCompiler.1 TS语法检查变更
4
5**访问级别**
6其它
7
8**变更原因**
9OpenHarmony SDK中TypeScript版本从4.2.3升级至4.9.5版本,支持TS语言的新语法特性以及提供更强的类型检查能力,但存在少数与之前版本不兼容的语法特性。
10
11**变更发生版本**
12OpenHarmony SDK 4.1.3.1
13
14**变更影响**
15TypeScript版本升级之后,TS类语法检查更加严格,有10类与现有语法不兼容的语法特性,下面进行具体介绍并给出简单的示例
16
17**变更语法特性与适配指导**
18
191. 不能将联合枚举类型的值与恒不等于的数字进行比较
20联合枚举类型:枚举的成员自动填充或简单写入,则视为联合枚举类型,这种情况下可以调用枚举可能表示的每个值
21下面为错误示例:
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    适配建议:通过toString()方法将数字转换为字符串进行比较
36
372. 对导入函数的更合规的间接调用
38   非esmodule(如FA模型下为commonjs模块)模块import场景下会丢弃this值,与esmodule模块的import行为一致
39   下面示例为调用行为的变化:
40   ```
41    // 假设这是我们导入的模块,它有一个'foo'以及'feature'的导出
42    let fooModule = {
43      foo() {
44        console.log(this);
45      },
46      feature: 'oh'
47    };
48
49    // 以前的调用方式如下:
50    fooModule.foo();  // 输出结果: { "feature": "oh" }
51
52    // 现在的调用方式如下(实际上是在调用 '(0, fooModule.foo), 与上面有细微的不同):
53    (0, fooModule.foo)();  // 输出结果: undefined
54   ```
553. 抽象属性不允许初始化
56抽象属性不允许初始化,以下代码现在是错误的
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    适配建议:删除初始化值
654. Rest参数语法会删除来自泛型对象中不可展开的成员
66从泛型对象中解构属性时,以前会假定所有属性都是可解构的,现在会严格分析属性是否可以被解构。不应该被解构的属性如:私有属性、私有方法、静态属性等。 下面为报错示例:
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    适配建议:从泛型对象中解构属性时,确保属性属于可结构类型
825. 对模板字符串表达式进行更严格的检查
83当在模板字符串中使用Symbol时,在JavaScript会报运行时错误,现在TS文件中,TS语法检查会报错,与之同时也会检查模板字符串中是否使用了某种方式来约束符号的泛型值。
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    适配建议:通过String包装表达式
926. Tuple元组有readonly属性时长度属性视为只读
93    只读Tuple元组现在将其长度属性(length)视为只读。
94    ```
95    function overwriteLength(tuple: readonly [string, string, string]) {
96        // Now errors.
97        tuple.length = 7;
98    }
99    ```
1007. 对象与Array Literal不允许比较
101JavaScript中对象(以及数组)之间的'==' 和 '===' 检查两个引用是否指向相同的值,现在会禁止下面的代码:
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. 不允许在类型签名中写未使用的重命名
111在TS文件中,开发者一般会认为下面示例中makePerson的入参是一个对象,其有name和age两个属性,string与number为两个属性的类型。然而此对象实际是一个析构语法,string与number是name与age的重命名。
112    ```
113    declare function makePerson({ name: string, age: number }): Person;
114    ```
115    正确的写法如下:
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. 检查NaN相等
122现在直接与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    适配建议:建议使用Number.isNaN来代替
13110. 类型推导与检查能力增强引发的报错
132TypeScript升级至4.9.5版本,其类型推导与检查能力增强,可能会检查出除上文介绍之外的语法错误。语法错误修正以后是有益处的,可提前发现运行时错误并帮助提高运行时性能。
133