HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(九)

鸿蒙时代
发布于 2024-7-25 11:11
浏览
0收藏

一、需要显式标注泛型函数类型实参
规则:arkts-no-inferred-generic-params
级别:错误
如果可以从传递给泛型函数的参数中推断出具体类型,ArkTS允许省略泛型类型实参。否则,省略泛型类型实参会发生编译时错误。
禁止仅基于泛型函数返回类型推断泛型类型参数。
TypeScript

function choose<T>(x: T, y: T): T {
  return Math.random() < 0.5 ? x: y;
}

let x = choose(10, 20);   // 推断choose<number>(...)
let y = choose('10', 20); // 编译时错误

function greet<T>(): T {
  return 'Hello' as T;
}
let z = greet() // T的类型被推断为“unknown”

ArkTS

function choose<T>(x: T, y: T): T {
  return Math.random() < 0.5 ? x: y;
}

let x = choose(10, 20);   // 推断choose<number>(...)
let y = choose('10', 20); // 编译时错误

function greet<T>(): T {
  return 'Hello' as T;
}
let z = greet<string>();

二、需要显式标注对象字面量的类型
规则:arkts-no-untyped-obj-literals
级别:错误
在ArkTS中,需要显式标注对象字面量的类型,否则,将发生编译时错误。在某些场景下,编译器可以根据上下文推断出字面量的类型。
在以下上下文中不支持使用字面量初始化类和接口:
初始化具有any、Object或object类型的任何对象
初始化带有方法的类或接口
初始化包含自定义含参数的构造函数的类
初始化带readonly字段的类
例子1
TypeScript

let o1 = {n: 42, s: 'foo'};
let o2: Object = {n: 42, s: 'foo'};
let o3: object = {n: 42, s: 'foo'};

let oo: Object[] = [{n: 1, s: '1'}, {n: 2, s: '2'}];

ArkTS

class C1 {
  n: number = 0
  s: string = ''
}

let o1: C1 = {n: 42, s: 'foo'};
let o2: C1 = {n: 42, s: 'foo'};
let o3: C1 = {n: 42, s: 'foo'};

let oo: C1[] = [{n: 1, s: '1'}, {n: 2, s: '2'}];

例子2
TypeScript

class C2 {
  s: string
  constructor(s: string) {
    this.s = 's =' + s;
  }
}
let o4: C2 = {s: 'foo'};

ArkTS

class C2 {
  s: string
  constructor(s: string) {
    this.s = 's =' + s;
  }
}
let o4 = new C2('foo');

例子3
TypeScript

class C3 {
  readonly n: number = 0
  readonly s: string = ''
}
let o5: C3 = {n: 42, s: 'foo'};

ArkTS

class C3 {
  n: number = 0
  s: string = ''
}
let o5: C3 = {n: 42, s: 'foo'};

例子4
TypeScript

abstract class A {}
let o6: A = {};

ArkTS

abstract class A {}
class C extends A {}
let o6: C = {}; // 或 let o6: C = new C()

例子5
TypeScript

class C4 {
  n: number = 0
  s: string = ''
  f() {
    console.log('Hello');
  }
}
let o7: C4 = {n: 42, s: 'foo', f: () => {}};

ArkTS

class C4 {
  n: number = 0
  s: string = ''
  f() {
    console.log('Hello');
  }
}
let o7 = new C4();
o7.n = 42;
o7.s = 'foo';

例子6
TypeScript

class Point {
  x: number = 0
  y: number = 0
}

function getPoint(o: Point): Point {
  return o;
}

// TS支持structural typing,可以推断p的类型为Point
let p = {x: 5, y: 10};
getPoint(p);

// 可通过上下文推断出对象字面量的类型为Point
getPoint({x: 5, y: 10});

ArkTS

class Point {
  x: number = 0
  y: number = 0

  // 在字面量初始化之前,使用constructor()创建一个有效对象。
  // 由于没有为Point定义构造函数,编译器将自动添加一个默认构造函数。
}

function getPoint(o: Point): Point {
  return o;
}

// 字面量初始化需要显式定义类型
let p: Point = {x: 5, y: 10};
getPoint(p);

// getPoint接受Point类型,字面量初始化生成一个Point的新实例
getPoint({x: 5, y: 10});

相关约束
对象字面量不能用于类型声明
数组字面量必须仅包含可推断类型的元素
三、对象字面量不能用于类型声明
规则:arkts-no-obj-literals-as-types
级别:错误
ArkTS不支持使用对象字面量声明类型,可以使用类或者接口声明类型。
TypeScript

let o: {x: number, y: number} = {
  x: 2,
  y: 3
}

type S = Set<{x: number, y: number}>

ArkTS

class O {
  x: number = 0
  y: number = 0
}

let o: O = {x: 2, y: 3};

type S = Set<O>

相关约束
对象字面量必须对应某些显式声明的类或接口
数组字面量必须仅包含可推断类型的元素

本文根据HarmonyOS NEXT Developer Beta1官方公开的开发文档整理而成。

分类
收藏
回复
举报
回复
    相关推荐