HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(九)
一、需要显式标注泛型函数类型实参
规则: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官方公开的开发文档整理而成。