18-ArkTs常见错误

18-ArkTs常见错误

arkts-no-untyped-obj-literals

用class为object literal标注类型,需要class的构造函数无参数

应用代码

class Test {  value: number = 1
  constructor(value: number) {    this.value = value;  }}
let t: Test = { value: 2 };

建议改法1

// 去除构造函数class Test {  value: number = 1}
let t: Test = { value: 2 };

建议改法2

// 使用newclass Test {  value: number = 1    constructor(value: number) {    this.value = value;  }}
let t: Test = new Test(2);

原因

class C {  value: number = 1    constructor(n: number) {    if (n < 0) {      throw new Error('Negative');    }    this.value = n;  }}
let s: C = new C(-2);     //抛出异常let t: C = { value: -2 };    //ArkTS不支持

例如在上面的例子中,如果允许使用C来标注object literal的类型,那么上述代码中的变量t会导致行为的二义性。ArkTS禁止通过object literal来绕过这一行为。

用class/interface为object literal标注类型,需要使用identifier作为object literal的key

应用代码

class Test {  value: number = 0}
let arr: Test[] = [  {    'value': 1  },  {    'value': 2  },  {    'value': 3  }]

建议改法

class Test {  value: number = 0}let arr: Test[] = [  {    value: 1  },  {    value: 2  },  {    value: 3  }]

使用Record为object literal标注类型,需要使用字符串作为object literal的key

应用代码

let obj: Record<string, number | string> = {  value: 123,  name: 'abc'}

建议改法

let obj: Record<string, number | string> = {  'value': 123,  'name': 'abc'}

函数参数类型包含index signature

应用代码

function foo(obj: { [key: string]: string}): string {  if (obj != undefined && obj != null) {    return obj.value1 + obj.value2;  }  return '';}

建议改法

function foo(obj: Record<string, string>): string {  if (obj != undefined && obj != null) {    return obj.value1 + obj.value2;  }  return '';}

函数实参使用了object literal

应用代码

(fn) => {  fn({ value: 123, name:'' });}

建议改法

class T {  value: number = 0  name: string = ''}
(fn: (v: T) => void) => {  fn({ value: 123, name: '' });}

class/interface 中包含方法

应用代码

interface T {  foo(value: number): number}
let t:T = { foo: (value) => { return value } };

建议改法1

interface T {  foo: (value: number) => number}
let t:T = { foo: (value) => { return value } };

建议改法2

class T {  foo: (value: number) => number = (value: number) => {    return value;  }}
let t:T = new T();

原因

class/interface中声明的方法应该被所有class的实例共享。ArkTS不支持通过object literal改写实例方法。ArkTS支持函数类型的属性。

export default对象

应用代码

export default {  onCreate() {    // ...  },  onDestroy() {    // ...  }}

建议改法

class Test {  onCreate() {    // ...  }  onDestroy() {    // ...  }}
export default new Test()

通过导入namespace获取类型

应用代码

// test.d.etsdeclare namespace test {  interface I {    id: string;    type: number;  }
  function foo(name: string, option: I): void;}
export default test;
// app.etsimport { test } from 'test';
let option = { id: '', type: 0 };test.foo('', option);

建议改法

// test.d.etsdeclare namespace test {  interface I {    id: string;    type: number;  }
  function foo(name: string, option: I): void;}
export default test;
// app.etsimport { test } from 'test';
let option: test.I = { id: '', type: 0 };test.foo('', option);

原因

对象字面量缺少类型,根据test.foo分析可以得知,option的类型来源于声明文件,那么只需要将类型导入即可。

注意到在test.d.ets中,I是定义在namespace中的,所以在ets文件中,先导入namespace,再通过名称获取相应的类型。

object literal传参给Object类型

应用代码

function emit(event: string, ...args: Object[]): void {}
emit('', {  'action': 11,  'outers': false});

建议改法

function emit(event: string, ...args: Object[]): void {}
let emitArg: Record<string, number | boolean> = {   'action': 11,   'outers': false}
emit('', emitArg);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万少-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值