14-从TypeScript到ArkTS的适配规则(4)

2024-12-12 21:17:10
127次阅读
0个评论

14-从TypeScript到ArkTS的适配规则(4)

不支持生成器函数

**规则:**arkts-no-generators

级别:错误

目前ArkTS不支持生成器函数,使用async或await机制进行并行任务处理。

TypeScript

function* counter(start: number, end: number) {  for (let i = start; i <= end; i++) {    yield i;  }}
for (let num of counter(1, 5)) {  console.log(num);}

ArkTS

async function complexNumberProcessing(num: number): Promise<number> {  // ...  return num;}
async function foo() {  for (let i = 1; i <= 5; i++) {    await complexNumberProcessing(i);  }}
foo()

使用instanceof和as进行类型保护

**规则:**arkts-no-is

级别:错误

ArkTS不支持is运算符,必须用instanceof运算符替代。在使用之前,必须使用as运算符将对象转换为需要的类型。

TypeScript

class Foo {  foo: string = ''  common: string = ''}
class Bar {  bar: string = ''  common: string = ''}
function isFoo(arg: any): arg is Foo {  return arg.foo !== undefined;}
function doStuff(arg: Foo | Bar) {  if (isFoo(arg)) {    console.log(arg.foo);  // OK    console.log(arg.bar);  // 编译时错误  } else {    console.log(arg.foo);  // 编译时错误    console.log(arg.bar);  // OK  }}
doStuff({ foo: 123, common: '123' });doStuff({ bar: 123, common: '123' });

ArkTS

class Foo {  foo: string = ''  common: string = ''}
class Bar {  bar: string = ''  common: string = ''}
function isFoo(arg: Object): boolean {  return arg instanceof Foo;}
function doStuff(arg: Object): void {  if (isFoo(arg)) {    let fooArg = arg as Foo;    console.log(fooArg.foo);   // OK    console.log(arg.bar);    // 编译时错误  } else {    let barArg = arg as Bar;    console.log(arg.foo);    // 编译时错误    console.log(barArg.bar);   // OK  }}
function main(): void {  doStuff(new Foo());  doStuff(new Bar());}

部分支持展开运算符

**规则:**arkts-no-spread

级别:错误

ArkTS仅支持使用展开运算符展开数组、Array的子类和TypedArray(例如Int32Array)。仅支持使用在以下场景中:

  1. 传递给剩余参数时
  2. 复制一个数组到数组字面量

TypeScript

function foo(x: number, y: number, z: number) {  // ...}
let args: [number, number, number] = [0, 1, 2];foo(...args);

ArkTS

function log_numbers(x: number, y: number, z: number) {  // ...}
let numbers: number[] = [1, 2, 3];log_numbers(numbers[0], numbers[1], numbers[2]);

TypeScript

let point2d = { x: 1, y: 2 };let point3d = { ...point2d, z: 3 };

ArkTS

class Point2D {  x: number = 0; y: number = 0}
class Point3D {  x: number = 0; y: number = 0; z: number = 0  constructor(p2d: Point2D, z: number) {    this.x = p2d.x;    this.y = p2d.y;    this.z = z;  }}
let p3d = new Point3D({ x: 1, y: 2 } as Point2D, 3);
class DerivedFromArray extends Uint16Array {};
let arr1 = [1, 2, 3];let arr2 = new Uint16Array([4, 5, 6]);let arr3 = new DerivedFromArray([7, 8, 9]);let arr4 = [...arr1, 10, ...arr2, 11, ...arr3];

接口不能继承具有相同方法的两个接口

**规则:**arkts-no-extend-same-prop

级别:错误

在TypeScript中,如果一个接口继承了具有相同方法的两个接口,则该接口必须使用联合类型来声明该方法的返回值类型。在ArkTS中,由于一个接口中不能包含两个无法区分的方法(例如两个参数列表相同但返回类型不同的方法),因此,接口不能继承具有相同方法的两个接口。

TypeScript

interface Mover {  getStatus(): { speed: number }}interface Shaker {  getStatus(): { frequency: number }}
interface MoverShaker extends Mover, Shaker {  getStatus(): {    speed: number    frequency: number  }}
class C implements MoverShaker {  private speed: number = 0  private frequency: number = 0
  getStatus() {    return { speed: this.speed, frequency: this.frequency };  }}

ArkTS

class MoveStatus {  public speed: number  constructor() {    this.speed = 0;  }}interface Mover {  getMoveStatus(): MoveStatus}
class ShakeStatus {  public frequency: number  constructor() {    this.frequency = 0;  }}interface Shaker {  getShakeStatus(): ShakeStatus}
class MoveAndShakeStatus {  public speed: number  public frequency: number  constructor() {    this.speed = 0;    this.frequency = 0;  }}
class C implements Mover, Shaker {  private move_status: MoveStatus  private shake_status: ShakeStatus
  constructor() {    this.move_status = new MoveStatus();    this.shake_status = new ShakeStatus();  }
  public getMoveStatus(): MoveStatus {    return this.move_status;  }
  public getShakeStatus(): ShakeStatus {    return this.shake_status;  }
  public getStatus(): MoveAndShakeStatus {    return {      speed: this.move_status.speed,      frequency: this.shake_status.frequency    };  }}

不支持声明合并

**规则:**arkts-no-decl-merging

级别:错误

ArkTS不支持类、接口的声明合并。

TypeScript

interface Document {  createElement(tagName: any): Element}
interface Document {  createElement(tagName: string): HTMLElement}
interface Document {  createElement(tagName: number): HTMLDivElement  createElement(tagName: boolean): HTMLSpanElement  createElement(tagName: string, value: number): HTMLCanvasElement}

ArkTS

interface Document {  createElement(tagName: number): HTMLDivElement  createElement(tagName: boolean): HTMLSpanElement  createElement(tagName: string, value: number): HTMLCanvasElement  createElement(tagName: string): HTMLElement  createElement(tagName: Object): Element}

接口不能继承类

**规则:**arkts-extends-only-class

级别:错误

ArkTS不支持接口继承类,接口只能继承接口。

TypeScript

class Control {  state: number = 0}
interface SelectableControl extends Control {  select(): void}

ArkTS

interface Control {  state: number}
interface SelectableControl extends Control {  select(): void}

不支持构造函数类型

**规则:**arkts-no-ctor-signatures-funcs

级别:错误

ArkTS不支持使用构造函数类型,改用lambda函数。

TypeScript

class Person {  constructor(    name: string,    age: number  ) {}}type PersonCtor = new (name: string, age: number) => Person
function createPerson(Ctor: PersonCtor, name: string, age: number): Person{  return new Ctor(name, age);}
const person = createPerson(Person, 'John', 30);

ArkTS

class Person {  constructor(    name: string,    age: number  ) {}}type PersonCtor = (n: string, a: number) => Person
function createPerson(Ctor: PersonCtor, n: string, a: number): Person {  return Ctor(n, a);}
let Impersonizer: PersonCtor = (n: string, a: number): Person => {  return new Person(n, a);}
const person = createPerson(Impersonizer, 'John', 30);

只能使用类型相同的编译时表达式初始化枚举成员

**规则:**arkts-no-enum-mixed-types

级别:错误

ArkTS不支持使用在运行期间才能计算的表达式来初始化枚举成员。此外,枚举中所有显式初始化的成员必须具有相同的类型。

TypeScript

enum E1 {  A = 0xa,  B = 0xb,  C = Math.random(),  D = 0xd,  E // 推断出0xe}
enum E2 {  A = 0xa,  B = '0xb',  C = 0xc,  D = '0xd'}

ArkTS

enum E1 {  A = 0xa,  B = 0xb,  C = 0xc,  D = 0xd,  E // 推断出0xe}
enum E2 {  A = '0xa',  B = '0xb',  C = '0xc',  D = '0xd'}

不支持enum声明合并

**规则:**arkts-no-enum-merging

级别:错误

ArkTS不支持enum声明合并。

TypeScript

enum ColorSet {  RED,  GREEN}enum ColorSet {  YELLOW = 2}enum ColorSet {  BLACK = 3,  BLUE}

ArkTS

enum ColorSet {  RED,  GREEN,  YELLOW,  BLACK,  BLUE}

命名空间不能被用作对象

**规则:**arkts-no-ns-as-obj

级别:错误

ArkTS不支持将命名空间用作对象,可以使用类或模块。

TypeScript

namespace MyNamespace {  export let x: number}
let m = MyNamespace;m.x = 2;

ArkTS

namespace MyNamespace {  export let x: number}
MyNamespace.x = 2;

不支持命名空间中的非声明语句

**规则:**arkts-no-ns-statements

级别:错误

在ArkTS中,命名空间用于定义标志符可见范围,只在编译时有效。因此,不支持命名空间中的非声明语句。可以将非声明语句写在函数中。

TypeScript

namespace A {  export let x: number  x = 1;}

ArkTS

namespace A {  export let x: number
  export function init() {    x = 1;  }}
// 调用初始化函数来执行A.init();

不支持require和import赋值表达式

**规则:**arkts-no-require

级别:错误

ArkTS不支持通过require导入,也不支持import赋值表达式,改用import。

TypeScript

import m = require('mod')

ArkTS

import * as m from 'mod'

不支持export = ...语法

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

级别:错误

ArkTS不支持export = ...语法,改用常规的export或import。

TypeScript

// module1export = Point
class Point {  constructor(x: number, y: number) {}  static origin = new Point(0, 0)}
// module2import Pt = require('module1')
let p = Pt.Point.origin;

ArkTS

// module1export class Point {  constructor(x: number, y: number) {}  static origin = new Point(0, 0)}
// module2import * as Pt from 'module1'
let p = Pt.Point.origin

不支持ambient module声明

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

级别:错误

由于ArkTS本身有与JavaScript交互的机制,ArkTS不支持ambient module声明。

TypeScript

declare module 'someModule' {  export function normalize(s: string): string;}

ArkTS

// 从原始模块中导入需要的内容import { normalize } from 'someModule'

不支持在模块名中使用通配符

**规则:**arkts-no-module-wildcards

级别:错误

由于在ArkTS中,导入是编译时而非运行时行为,因此,不支持在模块名中使用通配符。

TypeScript

// 声明declare module '*!text' {  const content: string  export default content}
// 使用代码import fileContent from 'some.txt!text'

ArkTS

// 声明declare namespace N {  function foo(x: number): number}
// 使用代码import * as m from 'module'console.log('N.foo called: ' + N.foo(42));

不支持通用模块定义(UMD)

**规则:**arkts-no-umd

级别:错误

ArkTS不支持通用模块定义(UMD)。因为在ArkTS中没有“脚本”的概念(相对于“模块”)。此外,在ArkTS中,导入是编译时而非运行时特性。改用export和import语法。

TypeScript

// math-lib.d.tsexport const isPrime(x: number): booleanexport as namespace mathLib
// 脚本中mathLib.isPrime(2)

ArkTS

// math-lib.d.tsnamespace mathLib {  export isPrime(x: number): boolean}
// 程序中import { mathLib } from 'math-lib'mathLib.isPrime(2)

不支持new.target

**规则:**arkts-no-new-target

级别:错误

ArkTS没有原型的概念,因此不支持new.target。此特性不符合静态类型的原则。

不支持确定赋值断言

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

级别:警告

ArkTS不支持确定赋值断言,例如:let v!: T。改为在声明变量的同时为变量赋值。

TypeScript

let x!: number // 提示:在使用前将x初始化
initialize();
function initialize() {  x = 10;}
console.log('x = ' + x);

ArkTS

function initialize(): number {  return 10;}
let x: number = initialize();
console.log('x = ' + x);
收藏00

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