16-从 TypeScript 到 ArkTS 的适配规则(6)

16-从 TypeScript 到 ArkTS 的适配规则(6)

强制进行严格类型检查

**规则:**arkts-strict-typing

级别:错误

在编译阶段,会进行TypeScript严格模式的类型检查,包括:

noImplicitReturns,

strictFunctionTypes,

strictNullChecks,

strictPropertyInitialization。

TypeScript

// 只有在开启noImplicitReturns选项时会产生编译时错误
function foo(s: string): string {
  if (s != '') {
    console.log(s);
    return s;
  } else {
    console.log(s);
  }
}

let n: number = null; // 只有在开启strictNullChecks选项时会产生编译时错误

ArkTS

function foo(s: string): string {
  console.log(s);
  return s;
}

let n1: number | null = null;
let n2: number = 0;

在定义类时,如果无法在声明时或者构造函数中初始化某实例属性,那么可以使用确定赋值断言符!来消除strictPropertyInitialization的报错。

使用确定赋值断言符会增加代码错误的风险,开发者需要保证该实例属性在被使用前已被赋值,否则可能会产生运行时异常。

使用确定赋值断言符会增加运行时的类型检查,从而增加额外的运行时开销,所以应尽可能避免使用确定赋值断言符。

使用确定赋值断言符将产生warning: arkts-no-definite-assignment。

TypeScript

class C {
  name: string  // 只有在开启strictPropertyInitialization选项时会产生编译时错误
  age: number   // 只有在开启strictPropertyInitialization选项时会产生编译时错误
}

let c = new C();

ArkTS

class C {
  name: string = ''
  age!: number      // warning: arkts-no-definite-assignment

  initAge(age: number) {
    this.age = age;
  }
}

let c = new C();
c.initAge(10);

不允许通过注释关闭类型检查

**规则:**arkts-strict-typing-required

级别:错误

在ArkTS中,类型检查不是可选项。不允许通过注释关闭类型检查,不支持使用@ts-ignore和@ts-nocheck。

TypeScript

// @ts-nocheck
// ...
// 关闭了类型检查后的代码
// ...

let s1: string = null; // 没有报错

// @ts-ignore
let s2: string = null; // 没有报错

ArkTS

let s1: string | null = null; // 没有报错,合适的类型
let s2: string = null; // 编译时报错

允许.ets文件import.ets/.ts/.js文件源码, 不允许.ts/.js文件import.ets文件源码

**规则:**arkts-no-ts-deps

级别:错误

.ets文件可以import.ets/.ts/.js文件源码,但是.ts/.js文件不允许import.ets文件源码。

TypeScript

// app.ets
export class C {
  // ...
}

// lib.ts
import { C } from 'app'

ArkTS

// lib1.ets
export class C {
  // ...
}

// lib2.ets
import { C } from 'lib1'

class不能被用作对象

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

级别:警告

在ArkTS中,class声明的是一个新的类型,不是一个值。因此,不支持将class用作对象(例如将class赋值给一个对象)。

不支持在import语句前使用其他语句

**规则:**arkts-no-misplaced-imports

级别:错误

在ArkTS中,除动态import语句外,所有import语句需要放在所有其他语句之前。

TypeScript

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

import foo from 'module1'

ArkTS

import foo from 'module1'

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

import('module2').then(() => {}).catch(() => {})  // 动态import

限制使用ESObject类型

**规则:**arkts-limited-esobj

级别:警告

为了防止动态对象(来自.ts/.js文件)在静态代码(.ets文件)中的滥用,ESObject类型在ArkTS中的使用是受限的。唯一允许使用ESObject类型的场景是将其用在局部变量的声明中。ESObject类型变量的赋值也是受限的,只能被来自跨语言调用的对象赋值,例如:ESObject、any、unknown、匿名类型等类型的变量。禁止使用静态类型的值(在.ets文件中定义的)初始化ESObject类型变量。ESObject类型变量只能用在跨语言调用的函数里或者赋值给另一个ESObject类型变量。

ArkTS

// lib.d.ts
declare function foo(): any;
declare function bar(a: any): number;

// main.ets
let e0: ESObject = foo(); // 编译时错误:ESObject类型只能用于局部变量

function f() {
  let e1 = foo();        // 编译时错误:e1的类型是any
  let e2: ESObject = 1;  // 编译时错误:不能用非动态值初始化ESObject类型变量
  let e3: ESObject = {}; // 编译时错误:不能用非动态值初始化ESObject类型变量
  let e4: ESObject = []; // 编译时错误:不能用非动态值初始化ESObject类型变量
  let e5: ESObject = ''; // 编译时错误:不能用非动态值初始化ESObject类型变量
  e5['prop'];            // 编译时错误:不能访问ESObject类型变量的属性
  e5[1];                 // 编译时错误:不能访问ESObject类型变量的属性
  e5.prop;               // 编译时错误:不能访问ESObject类型变量的属性

  let e6: ESObject = foo(); // OK,显式标注ESObject类型
  let e7 = e6;              // OK,使用ESObject类型赋值
  bar(e7);                  // OK,ESObject类型变量传给跨语言调用的函数
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

万少-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值