19-ArkTs常见错误
arkts-no-obj-literals-as-types
应用代码
type Person = { name: string, age: number }
建议改法
interface Person { name: string, age: number}
arkts-no-noninferrable-arr-literals
应用代码
let permissionList = [ { name: '设备信息', value: '用于分析设备的续航、通话、上网、SIM卡故障等' }, { name: '麦克风', value: '用于反馈问题单时增加语音' }, { name: '存储', value: '用于反馈问题单时增加本地文件附件' }]
建议改法
为对象字面量声明类型
class PermissionItem { name?: string value?: string}
let permissionList: PermissionItem[] = [ { name: '设备信息', value: '用于分析设备的续航、通话、上网、SIM卡故障等' }, { name: '麦克风', value: '用于反馈问题单时增加语音' }, { name: '存储', value: '用于反馈问题单时增加本地文件附件' }]
arkts-no-method-reassignment
应用代码
class C { add(left: number, right: number): number { return left + right; }}
function sub(left: number, right: number): number { return left - right;}
let c1 = new C();c1.add = sub;
建议改法
class C { add: (left: number, right: number) => number = (left: number, right: number) => { return left + right; }}
function sub(left: number, right: number): number { return left - right;}
let c1 = new C();c1.add = sub;
arkts-no-polymorphic-unops
应用代码
let a = +'5';let b = -'5';let c = ~'5';let d = +'string';
建议改法
let a = Number.parseInt('5');let b = -Number.parseInt('5');let c = ~Number.parseInt('5');let d = new Number('string');
arkts-no-type-query
应用代码
// module1.tsclass C { value: number = 0}
export let c = new C()
// module2.tsimport { c } from './module1'let t: typeof c = { value: 123 };
建议改法
// module1.tsclass C { value: number = 0}
export { C }
// module2.tsimport { C } from './module1'let t: C = { value: 123 };
arkts-no-in
使用Object.keys判断属性是否存在
应用代码
function test(str: string, obj: Record<string, Object>) { return str in obj;}
建议改法
function test(str: string, obj: Record<string, Object>) { for (let i of Object.keys(obj)) { if (i == str) { return true; } } return false;}
arkts-no-destruct-assignment
应用代码
let map = new Map<string, string>([['a', 'a'], ['b', 'b']]);for (let [key, value] of map) { console.log(key); console.log(value);}
建议改法
使用数组
let map = new Map<string, string>([['a', 'a'], ['b', 'b']]);for (let arr of map) { let key = arr[0]; let value = arr[1]; console.log(key); console.log(value);}
arkts-no-types-in-catch
应用代码
import { BusinessError } from '@kit.BasicServicesKit'
try { // ...} catch (e: BusinessError) { console.error(e.message, e.code);}
建议改法
import { BusinessError } from '@kit.BasicServicesKit'
try { // ...} catch (error) { let e: BusinessError = error as BusinessError; console.error(e.message, e.code);}
arkts-no-for-in
应用代码
interface Person { [name: string]: string}let p: Person = { name: 'tom', age: '18'};
for (let t in p) { console.log(p[t]); // log: "tom", "18" }
建议改法
let p: Record<string, string> = { 'name': 'tom', 'age': '18'};
for (let ele of Object.entries(p)) { console.log(ele[1]); // log: "tom", "18" }
arkts-no-mapped-types
应用代码
class C { a: number = 0 b: number = 0 c: number = 0}type OptionsFlags = { [Property in keyof C]: string}
建议改法
class C { a: number = 0 b: number = 0 c: number = 0}
type OptionsFlags = Record<keyof C, string>
arkts-limited-throw
应用代码
import { BusinessError } from '@kit.BasicServicesKit'
function ThrowError(error: BusinessError) { throw error;}
建议改法
import { BusinessError } from '@kit.BasicServicesKit'
function ThrowError(error: BusinessError) { throw error as Error;}
原因
throw语句中值的类型必须为Error或者其继承类,如果继承类是一个泛型,会有编译期报错。建议使用as将类型转换为Error。
arkts-no-standalone-this
函数内使用this
应用代码
function foo() { console.log(this.value);}
let obj = { value: 'abc' };foo.apply(obj);
建议改法1
使用类的方法实现,如果该方法被多个类使用,可以考虑采用继承的机制
class Test { value: string = '' constructor (value: string) { this.value = value } foo() { console.log(this.value); }}
let obj: Test = new Test('abc');obj.foo();
建议改法2
将this作为参数传入
function foo(obj: Test) { console.log(obj.value);}
class Test { value: string = ''}
let obj: Test = { value: 'abc' };foo(obj);
建议改法3
将属性作为参数传入
function foo(value: string) { console.log(value);}
class Test { value: string = ''}
let obj: Test = { value: 'abc' };foo(obj.value);
class的静态方法内使用this
应用代码
class Test { static value: number = 123 static foo(): number { return this.value }}
建议改法
class Test { static value: number = 123 static foo(): number { return Test.value }}
arkts-no-spread
应用代码
// test.d.etsdeclare namespace test { interface I { id: string; type: number; }
function foo(): I;}
export default test
// app.etsimport test from 'test';
let t: test.I = { ...test.foo(), type: 0}
建议改法
// test.d.etsdeclare namespace test { interface I { id: string; type: number; }
function foo(): I;}
export default test
// app.etsimport test from 'test';
let t: test.I = test.foo();t.type = 0;
原因
ArkTS中,对象布局在编译期是确定的。如果需要将一个对象的所有属性展开赋值给另一个对象可以通过逐个属性赋值语句完成。在本例中,需要展开的对象和赋值的目标对象类型恰好相同,可以通过改变该对象属性的方式重构代码。