首页 > 其他分享 >HarmonyOS NEXT - 从TypeScript到ArkTS的适配指导

HarmonyOS NEXT - 从TypeScript到ArkTS的适配指导

时间:2024-06-19 14:01:47浏览次数:11  
标签:ArkTS TypeScript string 适配 代码 undefined 编译 name

一:ArkTS语法适配背景
二:从TypeScript到ArkTS的适配规则
三:适配指导案例

ArkTS语法适配背景

 

ArkTS在保持TypeScript(简称TS)基本语法风格的基础上,进一步通过规范强化静态检查和分析,使得在程序开发期能检测更多错误,提升程序稳定性,并实现更好的运行性能。本文将进一步解释为什么建议将TS代码适配为ArkTS代码。

程序稳定性

动态类型语言,例如JavaScript(简称JS),可以使得开发者非常快速地编写代码,但是同时,它也使得程序容易在运行时产生非预期的错误。例如在代码中,如果开发者没有检查一个值是否为undefined,那么程序有可能在运行时崩溃,给开发者造成不便。如果能在代码开发阶段检查此类问题是更有好处的。TS通过标注类型帮助开发者检查错误,许多错误在编译时可以被编译器检测出来,不用等到程序运行时。但是,即使是TS也有局限性,它不强制要求对变量进行类型标注,导致很多编译时检查无法开展。ArkTS尝试克服这些缺点,它强制使用静态类型,旨在通过更严格的类型检查以减少运行时错误。

下面这个例子展示了ArkTS通过强制严格的类型检查来提高代码稳定性和正确性。

显式初始化类的属性

ArkTS要求类的所有属性在声明时或者在构造函数中显式地初始化,这和TS中的strictPropertyInitialization检查一致。以下的代码片段是非严格模式下的TS代码。
 

class Person {
  name: string // undefined
  
  setName(n: string): void {
    this.name = n
  }
  
  getName(): string {
  // 开发者使用"string"作为返回类型,这隐藏了name可能为"undefined"的事实。
  // 更合适的做法是将返回类型标注为"string | undefined",以告诉开发者这个API所有可能的返回值的类型。
    return this.name
  }
}

let buddy = new Person()
// 假设代码中没有对name的赋值,例如没有调用"buddy.setName('John')"
buddy.getName().length; // 运行时异常:name is undefined

由于ArkTS要求属性显式初始化,代码应该像下面这样写。
 

class Person {
  name: string = ''
  
  setName(n: string): void {
    this.name = n
  }
  
  // 类型为"string",不可能为"null"或者"undefined"
  getName(): string {
    return this.name
  }
}

let buddy = new Person()
// 假设代码中没有对name的赋值,例如没有调用"buddy.setName('John')"
buddy.getName().length; // 0, 没有运行时异常

如果name可以是undefined,那么它的类型应该在代码中被精确地标注。
 

class Person {
    name?: string // 可能为undefined

    setName(n: string): void {
        this.name = n
    }

    // 编译时错误:name可能为"undefined",所以不能将这个API的返回类型标注为"string"
    getNameWrong(): string {
        return this.name
    }

    getName(): string | undefined { // 返回类型匹配name的类型
        return this.name
    }
}

let buddy = new Person()
// 假设代码中没有对name的赋值,例如没有调用"buddy.setName('John')"

// 编译时错误:编译器认为下一行代码有可能访问"undefined"的属性,报错
buddy.getName().length;  // 编译失败

buddy.getName()?.length; // 编译成功,没有运行时错误

程序性能

为了保证程序的正确性,动态类型语言不得不在运行时检查对象的类型。例如,JS不允许访问undefined的属性。但是检查一个值是否为undefined的唯一的办法是在运行时进行一次类型检查。所有的JS引擎都会做如下的事:如果一个值不是undefined,那么可以访问其属性,否则抛出异常。现代JS引擎可以很好地对这类操作进行优化,但是总有一些运行时的检查是无法被消除的,这就使得程序变慢了。由于TS总是先被编译成JS,所以在TS代码中,也会面临相同的问题。ArkTS解决了这个问题。由于使能了静态类型检查,ArkTS代码将会被编译成方舟字节码文件,而不是JS代码。因此,ArkTS运行速度更快,更容易被进一步地优化。

Null Safety
 

function notify(who: string, what: string) {
  console.log(`Dear ${who}, a message for you: ${what}`)
}

notify('Jack', 'You look great today')

在大多数情况下,函数notify会接受两个string类型的变量作为输入,产生一个新的字符串。但是,如果将一些特殊值作为输入,例如notify(null, undefined),情况会怎么样呢?

程序仍会正常运行,输出预期值:Dear undefined, a message for you: null。一切看起来正常,但是请注意,为了保证该场景下程序的正确性,引擎总是在运行时进行类型检查,执行类似以下的伪代码。
 

function __internal_tostring(s: any): string {
  if (typeof s === 'string')
    return s
  if (s === undefined)
    return 'undefined'
  if (s === null)
    return 'null'
  // ...
}

现在想象一下,如果函数notify是某些复杂的负载场景中的一部分,而不仅仅是打印日志,那么在运行时执行像__internal_tostring的类型检查将会是一个性能问题。

如果可以保证在运行时,只有string类型的值(不会是其他值,例如null或者undefined)可以被传入函数notify呢?在这种情况下,因为可以确保没有其他边界情况,像__internal_tostring的检查就是多余的了。对于这个场景,这样的机制叫做“null-safety”,也就是说,保证null不是一个合法的string类型变量的值。如果ArkTS有了这个特性,类型不符合的代码将无法编译。
 

function notify(who: string, what: string) {
  console.log(`Dear ${who}, a message for you: ${what}`)
}

notify('Jack', 'You look great today')
notify(null, undefined) // 编译时错误

TS通过打开编译选项strictNullChecks来实现此特性。但是TS是被编译成JS的,而JS没有这个特性,因此严格null检查只在编译时起作用。从程序稳定性和性能角度考虑,ArkTS将“null-safety”视为一个重要的特性。这就是为什么ArkTS强制进行严格null检查,在ArkTS中,上面的代码总是编译报错。作为交换,这样的代码可以给ArkTS引擎带来更多的信息和有关值的类型保证,这有助于更好地优化性能。

.ets代码兼容性

在API version 10之前,ArkTS(.ets文件)完全采用了标准TS的语法。从API version 10 Release起,ArkTS的语法规则基于上述设计考虑进行了明确定义,同时,SDK增加了在编译流程中对.ets文件的ArkTS语法检查,通过编译告警或编译失败提示开发者适配新的ArkTS语法。

根据工程的compatibleSdkVersion,具体策略如下:

  • compatibleSdkVersion >= 10 为标准模式。在该模式下,对.ets文件,违反ArkTS语法规则的代码会导致工程编译失败,需要完全适配ArkTS语法后方可编译成功。
  • compatibleSdkVersion < 10 为兼容模式。在该模式下,对.ets文件,以warning形式提示违反ArkTS语法规则的所有代码。尽管违反ArkTS语法规则的工程在兼容模式下仍可编译成功,但是需要完全适配ArkTS语法后方可在标准模式下编译成功。

兼容TS/JS的约束

在API version 11上,OpenHarmony SDK中的TypeScript版本为4.9.5,target字段为es2017。开发者可以使用ECMA2017+的语法进行应用开发。

应用环境限制

  1. 强制使用严格模式(use strict)
  2. 禁止使用eval()
  3. 禁止使用with() {}
  4. 禁止以字符串为代码创建函数

标签:ArkTS,TypeScript,string,适配,代码,undefined,编译,name
From: https://blog.csdn.net/u011143672/article/details/139742448

相关文章

  • HarmonyOS NEXT - ArkTS语言 - 模块、关键字、空安全
    模块程序可划分为多组编译单元或模块。每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中。导出可以使用关键字export导出顶层的声明......
  • Android 屏幕适配
    目录一、目的二、环境三、相关概念3.1屏幕尺寸(screensize)3.2屏幕分辨率(Resolution)3.3像素(pixel)3.4ppi3.5dpi3.6dp/dip3.7sp四、Q&A4.1为啥dpi=160?4.2为啥Android要引入dp概念?五、代码仓库地址六、参考资料一、目的        最近在调试一款设备,发现视......
  • TypeScript中never类型的妙用
    本文由ChatMoney团队出品妙用一当我们在一个项目中,可能会去改动一个在整个项目中应用很广泛的函数的参数类型,但是可能由于代码量比较庞大,我们不好排查改了之后哪些地方会出现问题,此时我们可以使用never类型来辅助我们的函数,当我们在原有的类型基础上添加了新的类型时,可能会导......
  • TypeScript中never类型的实用技巧
    本文由ChatMoney团队出品妙用一当我们在一个项目中,可能会去改动一个在整个项目中应用很广泛的函数的参数类型,但是可能由于代码量比较庞大,我们不好排查改了之后哪些地方会出现问题,此时我们可以使用never类型来辅助我们的函数,当我们在原有的类型基础上添加了新的类型时,可能会导......
  • ArkTS本地化数据库SqlLight使用,鸿蒙NEXT星河版API(11)
    RelationalStore提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。结果......
  • TypeScript
    目录前言一、TypeScript简介安装TypeScriptTypeScript语法基础变量函数类接口继承模块二、TypeScript类型系统数组对象枚举字面量类型推导类型保护条件类型映射类型三、TypeScript高级特性类型映射类型别名交叉类型重叠类型布尔类型不存在类......
  • 鸿蒙ArkTS声明式开发:跨平台支持列表【点击回弹效果】 通用属性
    点击回弹效果设置组件点击时回弹效果。说明:从APIVersion10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。属性名称参数类型描述clickEffect[ClickEffect]nullClickEffect对象说明名称参数类型必填描述level[ClickEffectLevel]是设置当前......
  • 鸿蒙ArkTS声明式开发:跨平台支持列表【无障碍属性】 通用属性
    无障碍属性组件可以设置相应的无障碍属性和事件来更好地使用无障碍能力。说明:从APIVersion10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。属性名称参数类型描述accessibilityGroupboolean无障碍组,设置为true时表示该组件及其所有子组件......
  • 鸿蒙ArkTS声明式开发:跨平台支持列表【触摸热区设置】触摸交互控制
    触摸热区设置适用于支持通用点击事件、通用触摸事件、通用手势处理的组件。说明:从APIVersion8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。属性名称参数类型描述responseRegionArray<[Rectangle]>[Rectangle]Rectangle对象说明从APIv......
  • 大学专业选择的岔路口:计算机相关专业的前景与适配性
    随着2024年高考落幕,数百万高三学生即将面临人生中的重要抉择:选择大学专业。在这个关键节点,计算机相关专业是否仍是“万金油”的选择?在过去很长一段时间里,计算机科学与技术、人工智能、网络安全、软件工程等专业一直以来是炙手可热的存在,吸引了大批学生前往。然而,随着行业竞争......