13-从TypeScript到ArkTS的适配规则(3)

2024-12-12 21:16:56
247次阅读
0个评论

13-从TypeScript到ArkTS的适配规则(3)

类型转换仅支持as T语法

**规则:**arkts-as-casts

级别:错误

在ArkTS中,as关键字是类型转换的唯一语法,错误的类型转换会导致编译时错误或者运行时抛出ClassCastException异常。ArkTS不支持使用语法进行类型转换。

当需要将primitive类型(如number或boolean)转换成引用类型时,请使用new表达式。

TypeScript

class Shape {}class Circle extends Shape { x: number = 5 }class Square extends Shape { y: string = 'a' }
function createShape(): Shape {  return new Circle();}
let c1 = <Circle> createShape();
let c2 = createShape() as Circle;
// 如果转换错误,不会产生编译时或运行时报错let c3 = createShape() as Square;console.log(c3.y); // undefined
// 在TS中,由于`as`关键字不会在运行时生效,所以`instanceof`的左操作数不会在运行时被装箱成引用类型let e1 = (5.0 as Number) instanceof Number; // false
// 创建Number对象,获得预期结果:let e2 = (new Number(5.0)) instanceof Number; // true

ArkTS

class Shape {}class Circle extends Shape { x: number = 5 }class Square extends Shape { y: string = 'a' }
function createShape(): Shape {  return new Circle();}
let c2 = createShape() as Circle;
// 运行时抛出ClassCastException异常:let c3 = createShape() as Square;
// 创建Number对象,获得预期结果:let e2 = (new Number(5.0)) instanceof Number; // true

不支持JSX表达式

**规则:**arkts-no-jsx

级别:错误

不支持使用JSX。

一元运算符+、-和~仅适用于数值类型

**规则:**arkts-no-polymorphic-unops

级别:错误

ArkTS仅允许一元运算符用于数值类型,否则会发生编译时错误。与TypeScript不同,ArkTS不支持隐式将字符串转换成数值,必须进行显式转换。

TypeScript

let a = +5;    // 5(number类型)let b = +'5';    // 5(number类型)let c = -5;    // -5(number类型)let d = -'5';    // -5(number类型)let e = ~5;    // -6(number类型)let f = ~'5';    // -6(number类型)let g = +'string'; // NaN(number类型)
function returnTen(): string {  return '-10';}
function returnString(): string {  return 'string';}
let x = +returnTen();  // -10(number类型)let y = +returnString(); // NaN

ArkTS

let a = +5;    // 5(number类型)let b = +'5';    // 编译时错误let c = -5;    // -5(number类型)let d = -'5';    // 编译时错误let e = ~5;    // -6(number类型)let f = ~'5';    // 编译时错误let g = +'string'; // 编译时错误
function returnTen(): string {  return '-10';}
function returnString(): string {  return 'string';}
let x = +returnTen();  // 编译时错误let y = +returnString(); // 编译时错误

不支持delete运算符

**规则:**arkts-no-delete

级别:错误

ArkTS中,对象布局在编译时就确定了,且不能在运行时被更改。因此,删除属性的操作没有意义。

TypeScript

class Point {  x?: number = 0.0  y?: number = 0.0}
let p = new Point();delete p.y;

ArkTS

// 可以声明一个可空类型并使用null作为缺省值class Point {  x: number | null = 0  y: number | null = 0}
let p = new Point();p.y = null;

仅允许在表达式中使用typeof运算符

**规则:**arkts-no-type-query

级别:错误

ArkTS仅支持在表达式中使用typeof运算符,不允许使用typeof作为类型。

TypeScript

let n1 = 42;let s1 = 'foo';console.log(typeof n1); // 'number'console.log(typeof s1); // 'string'let n2: typeof n1let s2: typeof s1

ArkTS

let n1 = 42;let s1 = 'foo';console.log(typeof n1); // 'number'console.log(typeof s1); // 'string'let n2: numberlet s2: string

部分支持instanceof运算符

**规则:**arkts-instanceof-ref-types

级别:错误

在TypeScript中,instanceof运算符的左操作数的类型必须为any类型、对象类型,或者它是类型参数,否则结果为false。在ArkTS中,instanceof运算符的左操作数的类型必须为引用类型(例如,对象、数组或者函数),否则会发生编译时错误。此外,在ArkTS中,instanceof运算符的左操作数不能是类型,必须是对象的实例。

不支持in运算符

**规则:**arkts-no-in

级别:错误

由于在ArkTS中,对象布局在编译时是已知的并且在运行时无法修改,因此,不支持in运算符。如果仍需检查某些类成员是否存在,使用instanceof代替。

TypeScript

class Person {  name: string = ''}let p = new Person();
let b = 'name' in p; // true

ArkTS

class Person {  name: string = ''}let p = new Person();
let b = p instanceof Person; // true,且属性name一定存在

不支持解构赋值

**规则:**arkts-no-destruct-assignment

级别:错误

ArkTS不支持解构赋值。可使用其他替代方法,例如,使用临时变量。

TypeScript

let [one, two] = [1, 2]; // 此处需要分号[one, two] = [two, one];
let head, tail[head, ...tail] = [1, 2, 3, 4];

ArkTS

let arr: number[] = [1, 2];let one = arr[0];let two = arr[1];
let tmp = one;one = two;two = tmp;
let data: Number[] = [1, 2, 3, 4];let head = data[0];let tail: Number[] = [];for (let i = 1; i < data.length; ++i) {  tail.push(data[i]);}

逗号运算符,仅用在for循环语句中

**规则:**arkts-no-comma-outside-loops

级别:错误

为了方便理解执行顺序,在ArkTS中,逗号运算符仅适用于for循环语句中。注意与声明变量、函数参数传递时的逗号分隔符不同。

TypeScript

for (let i = 0, j = 0; i < 10; ++i, j += 2) {  // ...}
let x = 0;x = (++x, x++); // 1

ArkTS

for (let i = 0, j = 0; i < 10; ++i, j += 2) {  // ...}
// 通过语句表示执行顺序,而非逗号运算符let x = 0;++x;x = x++;

不支持解构变量声明

**规则:**arkts-no-destruct-decls

级别:错误

ArkTS不支持解构变量声明。它是一个依赖于结构兼容性的动态特性并且解构声明中的名称必须和被解构对象中的属性名称一致。

TypeScript

class Point {  x: number = 0.0  y: number = 0.0}
function returnZeroPoint(): Point {  return new Point();}
let {x, y} = returnZeroPoint();

ArkTS

class Point {  x: number = 0.0  y: number = 0.0}
function returnZeroPoint(): Point {  return new Point();}
// 创建一个局部变量来处理每个字段let zp = returnZeroPoint();let x = zp.x;let y = zp.y;

不支持在catch语句标注类型

**规则:**arkts-no-types-in-catch

级别:错误

在TypeScript的catch语句中,只能标注any或unknown类型。由于ArkTS不支持这些类型,应省略类型标注。

TypeScript

try {  // ...} catch (a: unknown) {  // 处理异常}

ArkTS

try {  // ...} catch (a) {  // 处理异常}

不支持for .. in

**规则:**arkts-no-for-in

级别:错误

由于在ArkTS中,对象布局在编译时是确定的、并且不能在运行时被改变,所以不支持使用for .. in迭代一个对象的属性。对于数组来说,可以使用常规的for循环。

TypeScript

let a: string[] = ['1.0', '2.0', '3.0'];for (let i in a) {  console.log(a[i]);}

ArkTS

let a: string[] = ['1.0', '2.0', '3.0'];for (let i = 0; i < a.length; ++i) {  console.log(a[i]);}

不支持映射类型

**规则:**arkts-no-mapped-types

级别:错误

ArkTS不支持映射类型,使用其他语法来表示相同的语义。

TypeScript

type OptionsFlags<Type> = {  [Property in keyof Type]: boolean}

ArkTS

class C {  n: number = 0  s: string = ''}
class CFlags {  n: boolean = false  s: boolean = false}

不支持with语句

**规则:**arkts-no-with

级别:错误

ArkTS不支持with语句,使用其他语法来表示相同的语义。

TypeScript

with (Math) { // 编译时错误, 但是仍能生成JavaScript代码  let r: number = 42;  let area: number = PI * r * r;}

ArkTS

let r: number = 42;let area: number = Math.PI * r * r;

限制throw语句中表达式的类型

**规则:**arkts-limited-throw

级别:错误

ArkTS只支持抛出Error类或其派生类的实例。禁止抛出其他类型(例如number或string)的数据。

TypeScript

throw 4;throw '';throw new Error();

ArkTS

throw new Error();

限制省略函数返回类型标注

**规则:**arkts-no-implicit-return-types

级别:错误

ArkTS在部分场景中支持对函数返回类型进行推断。当return语句中的表达式是对某个函数或方法进行调用,且该函数或方法的返回类型没有被显著标注时,会出现编译时错误。在这种情况下,请标注函数返回类型。

TypeScript

// 只有在开启noImplicitAny选项时会产生编译时错误function f(x: number) {  if (x <= 0) {    return x;  }  return g(x);}
// 只有在开启noImplicitAny选项时会产生编译时错误function g(x: number) {  return f(x - 1);}
function doOperation(x: number, y: number) {  return x + y;}
f(10);doOperation(2, 3);

ArkTS

// 需标注返回类型:function f(x: number): number {  if (x <= 0) {    return x;  }  return g(x);}
// 可以省略返回类型,返回类型可以从f的类型标注推导得到function g(x: number): number {  return f(x - 1);}
// 可以省略返回类型function doOperation(x: number, y: number) {  return x + y;}
f(10);doOperation(2, 3);

不支持参数解构的函数声明

**规则:**arkts-no-destruct-params

级别:错误

ArkTS要求实参必须直接传递给函数,且必须指定到形参。

TypeScript

function drawText({ text = '', location: [x, y] = [0, 0], bold = false }) {  text;  x;  y;  bold;}
drawText({ text: 'Hello, world!', location: [100, 50], bold: true });

ArkTS

function drawText(text: String, location: number[], bold: boolean) {  let x = location[0];  let y = location[1];  text;  x;  y;  bold;}
function main() {  drawText('Hello, world!', [100, 50], true);}

不支持在函数内声明函数

**规则:**arkts-no-nested-funcs

级别:错误

ArkTS不支持在函数内声明函数,改用lambda函数。

TypeScript

function addNum(a: number, b: number): void {
  // 函数内声明函数  function logToConsole(message: string): void {    console.log(message);  }
  let result = a + b;
  // 调用函数  logToConsole('result is ' + result);}

ArkTS

function addNum(a: number, b: number): void {  // 使用lambda函数代替声明函数  let logToConsole: (message: string) => void = (message: string): void => {    console.log(message);  }
  let result = a + b;
  logToConsole('result is ' + result);}

不支持在函数和类的静态方法中使用this

**规则:**arkts-no-standalone-this

级别:错误

ArkTS不支持在函数和类的静态方法中使用this,只能在类的实例方法中使用this。

TypeScript

function foo(i: string) {  this.count = i; // 只有在开启noImplicitThis选项时会产生编译时错误}
class A {  count: string = 'a'  m = foo}
let a = new A();console.log(a.count); // 打印aa.m('b');console.log(a.count); // 打印b

ArkTS

class A {  count: string = 'a'  m(i: string): void {    this.count = i;  }}
function main(): void {  let a = new A();  console.log(a.count);  // 打印a  a.m('b');  console.log(a.count);  // 打印b}
收藏00

登录 后评论。没有帐号? 注册 一个。