鸿蒙开发入门指南:从前端TypeScript到ArkTS过渡指南

鸿蒙开发入门指南:从前端TypeScript到ArkTS过渡指南

鸿蒙开发入门指南:从前端TypeScript到ArkTS过渡指南

大家好,我是木斯佳。

很多从前端转鸿蒙的朋友,第一次接触ArkTS时都会有这样的疑惑:

在这里插入图片描述
“这不就是TypeScript吗?为什么我的TS代码复制进去就报错?”
“ArkTS到底改了啥?我写了这么多年的TS,现在要重新学?”

别慌。今天这篇文章,我就用跨端开发者的视角,帮你彻底理清从TS到ArkTS的过渡容易坑的点。文章有点长,但保证你看完就能懂,懂了就能改。


一、先理解最核心的一句话

ArkTS = TypeScript - 动态特性 + 更严格的静态检查

就这么简单。

ArkTS保留了TS的大部分语法,但砍掉了一些影响性能和稳定性的动态特性,同时加强了编译时的类型检查。这么做的目的是什么?

  • 程序更稳定:运行时少报错
  • 性能更好:减少运行时的类型检查
  • 代码更清晰:类型一目了然

说白了,就是用开发时的“麻烦”换运行时的“顺畅”


二、为什么要从TS迁移到ArkTS?

一部分是像我这种前端开发,编程习惯导致很多时候肌肉记忆写出来的代码在鸿蒙编译不通过。
另外在工程化上,我们有很多web三方的utils库是非常经典的,在造轮子的过程中,不可避免的会从一个范式到另一个范式的迁移过渡。

2.1 程序稳定性:把错误扼杀在编译阶段

动态类型语言(比如JavaScript)虽然开发爽,但运行时容易翻车。最典型的就是undefined错误

// TypeScript(非严格模式)classPerson{ name:string;// 没初始化,实际是undefinedgetName():string{returnthis.name;// 返回类型写string,但实际可能是undefined}}let buddy =newPerson(); buddy.getName().length;// 运行时崩溃:name is undefined

这个问题在TS里可能被忽略,但在ArkTS里根本编译不过

// ArkTSclassPerson{ name:string='';// 必须显式初始化getName():string{returnthis.name;// 现在保证是string,不会是undefined}}let buddy =newPerson(); buddy.getName().length;// 0,安全运行

如果name真的可能为空,那就得明确写出来:

classPerson{ name?:string;// 可能为undefinedgetName():string|undefined{// 返回类型也要匹配returnthis.name;}} buddy.getName()?.length;// 必须用可选链,否则编译报错

2.2 程序性能:减少运行时的类型检查

JavaScript引擎为了处理动态类型,需要在运行时做大量检查。比如这个简单的函数:

functionnotify(who:string, what:string){console.info(`Dear ${who}, a message for you: ${what}`);}

在JS里,如果有人调用notify(null, undefined),引擎就得做类似这样的检查:

function__internal_tostring(s){if(typeof s ==='string')return s;if(s ===undefined)return'undefined';if(s ===null)return'null';// ...}

ArkTS通过强制静态类型,保证运行时不会出现非string类型的值,这些检查就可以省略,性能自然就上去了。


三、迁移核心:从“能用”到“规范”

3.1 最需要改的10条规则(新手必看)

下面是我总结的、迁移中最常遇到的10条规则,看完就能上手改代码。

规则1:使用let,别用var(arkts-no-var)

错误

var x =10;

正确

let x =10;
规则2:别用any和unknown(arkts-no-any-unknown)

错误

let value:any='hello'; value =42;// 随便改类型

正确

let value:string='hello';// 明确类型// 或者如果真的需要多种类型let value2:string|number='hello'; value2 =42;// 合法
规则3:类的属性必须初始化(编译强制)

错误

classPerson{ name:string;// 没初始化 age:number;// 没初始化}

正确

classPerson{ name:string=''; age:number=0;// 或者在构造函数里初始化constructor(name:string, age:number){this.name = name;this.age = age;}}
规则4:构造函数里不能声明字段(arkts-no-ctor-prop-decls)

错误(TS的简写语法):

classPerson{constructor(private name:string,// 直接在参数里声明字段public age:number){}}

正确

classPerson{private name:string;public age:number;constructor(name:string, age:number){this.name = name;this.age = age;}}
规则5:用箭头函数,别用函数表达式(arkts-no-func-expressions)

错误

letf=function(s:string){console.info(s);}

正确

letf=(s:string)=>{console.info(s);}
规则6:用点访问属性,别用方括号(arkts-no-props-by-index)

错误

let obj ={ name:'John'};console.info(obj['name']);// 索引访问

正确

let obj ={ name:'John'};console.info(obj.name);// 点访问
规则7:类型转换用as,别用尖括号(arkts-as-casts)

错误

let value =<string>someVar;// TS风格

正确

let value = someVar asstring;// ArkTS风格
规则8:别用解构赋值(arkts-no-destruct-assignment)

错误

let[a, b]=[1,2];[a, b]=[b, a];// 交换变量

正确

let arr =[1,2];let a = arr[0];let b = arr[1];let tmp = a; a = b; b = tmp;
规则9:别用for…in,用普通for循环(arkts-no-for-in)

错误

let arr =['a','b','c'];for(let i in arr){console.info(arr[i]);}

正确

let arr =['a','b','c'];for(let i =0; i < arr.length; i++){console.info(arr[i]);}// 或者用for...of(支持)for(let item of arr){console.info(item);}
规则10:throw只能抛Error对象(arkts-limited-throw)

错误

throw'出错了';// 抛字符串throw404;// 抛数字

正确

thrownewError('出错了');

四、进阶迁移:这些特性ArkTS不支持

4.1 不支持动态修改对象

在ArkTS里,对象的布局是固定的,不能在运行时添加或删除属性。

classPoint{ x:number=0; y:number=0;}let p =newPoint();// 以下操作都不允许delete p.x;// 编译错误 p.z =10;// 编译错误(p asany).z =10;// 编译错误(不能用any绕过)

怎么改:在设计类的时候就把所有可能的属性都定义好。

4.2 不支持structural typing

在TS里,只要两个类结构一样,就可以互相赋值:

// TypeScriptclassT{ name:string='';greet(){console.info('Hello');}}classU{ name:string='';greet(){console.info('Greetings');}}let u:U=newT();// TS里合法,结构相同

ArkTS不支持这个,必须通过继承实现接口来建立关系:

// ArkTSinterfaceGreetable{ name:string;greet():void;}classTimplementsGreetable{ name:string='';greet(){console.info('Hello');}}classUimplementsGreetable{ name:string='';greet(){console.info('Greetings');}}let u: Greetable =newT();// 合法,都实现了相同接口

4.3 不支持运算符重载

ArkTS对一元运算符有严格限制,只能用于数值类型:

let a =+5;// 合法let b =+'5';// 编译错误,不能把字符串转数值let c =-'5';// 编译错误// 需要显式转换let d =Number('5');// 正确做法

4.4 不支持解构声明

// 错误let{x, y}= point;// 正确let x = point.x;let y = point.y;

五、迁移实战:一个真实案例

假设我们有一个TS写的工具类,看看怎么迁移到ArkTS。

TS原版代码

在这里插入图片描述
// utils.tsclassLogger{ level:string;// 没初始化constructor(level?:string){if(level){this.level = level;}}log(message:string){console[this.level](message);// 可能报错}}// 使用let logger =newLogger(); logger.log('hello');// 运行时崩溃:this.level是undefined

ArkTS迁移后

在这里插入图片描述
// utils.etsclassLogger{ level:string='log';// 给个默认值constructor(level?:string){if(level){this.level = level;}}log(message:string){// 安全访问if(this.level ){}else{console.log(message);}}}// 使用let logger =newLogger(); logger.log('hello');// 安全运行

六、兼容性说明:版本差异要注意

6.1 根据SDK版本的不同

compatibleSdkVersion模式行为
>= 10标准模式必须严格遵循ArkTS语法,否则编译失败
< 10兼容模式违反规则只给警告,仍可编译成功

建议:新项目直接上标准模式,老项目逐步迁移。

6.2 文件引用规则

  • .ets文件可以import .ets/.ts/.js文件
  • .ts/.js文件不能import .ets文件

这意味着核心逻辑最好写在.ets文件里,避免循环依赖。


七、迁移清单:照着这个改就行

必改项(编译错误)

  • var改成let
  • 去掉所有anyunknown
  • 类的属性必须初始化
  • 构造函数参数里不能声明字段
  • 函数表达式改成箭头函数
  • 属性访问用点,别用方括号
  • 类型转换用as,别用尖括号
  • 去掉解构赋值
  • for...in改成for循环或for...of
  • throw只能抛Error对象

建议改(警告)

  • 不要用Function.bind/call/apply
  • 不要用globalThis
  • 不要用as const
  • 不要用@ts-ignore(ArkTS里直接报错)

八、总结:一张表记住TS和ArkTS的核心差异

特性TypeScriptArkTS迁移建议
类型系统渐进式强制静态所有变量都要有明确类型
any类型支持❌ 不支持用具体类型或联合类型替代
属性初始化可选必须声明时就初始化或在构造函数里初始化
解构赋值支持❌ 不支持拆开写
for...in支持❌ 不支持forfor...of
对象动态属性支持❌ 不支持类里预先定义好所有属性
throw类型任意只能是Errorthrow new Error()
this使用任意位置仅限于实例方法静态方法和函数里不能用this
文件引用任意.ets不能被子.ts引用核心逻辑写在.ets

结语:写给正在迁移代码的你

写完这篇迁移指南,我想和你聊几句心里话。

说实话,刚接触ArkTS的时候,我也觉得挺烦的——明明TS写得好好的,为什么要改?明明any多方便,为什么不让用?

但真正把代码迁移过来之后,我才理解了这个设计的良苦用心。

你发现没有?ArkTS砍掉的这些特性,恰恰是我们在TS里最容易踩坑的地方:

  • any一时爽,重构火葬场
  • 属性不初始化,运行时undefined报错
  • 解构赋值看起来很酷,但类型推导经常出问题
  • 动态添加属性,代码越写越乱

ArkTS的做法,相当于帮你把“可以偷懒但容易翻车”的路都堵上了。刚开始会觉得不习惯,但写久了你会发现:代码更稳了,bug更少了,团队协作也更顺畅了

迁移的过程,其实就是从“能用”走向“规范”的过程。

刚开始可能会慢一点,但每改一个any,每初始化一个属性,你都在为自己的代码增加一分稳定性,为未来的自己减少一个debug的夜晚。

  1. 从新模块开始:别想着一次性迁移整个项目,新写的代码直接用ArkTS规范,老代码逐步改造
  2. 用好编译错误:ArkTS的编译器很严格,但它报的错都是为你好的。每修复一个错误,就少了一个潜在的运行时bug
  3. 保持学习心态:刚开始会觉得约束太多,但慢慢你会发现,这些约束其实是在帮你建立更好的编码习惯
  4. 遇到问题多思考:不要简单地“把报错改掉”,而是理解为什么报错,ArkTS想让你怎么写更好

技术这条路很长,从一个框架到另一个框架,从一种范式到另一种范式,每一次迁移都是一次成长。

在这里插入图片描述

我是木斯佳,希望这篇指南能帮你在鸿蒙的世界里少踩几个坑。下篇见。

Read more

免费无限量API调用 GLM-5、Qwen3.5-398B 使用教程(AtomGit 限时开放)

免费无限量API调用 GLM-5、Qwen3.5-398B 使用教程(AtomGit 限时开放)

免费无限量API调用 GLM-5、Qwen3.5-398B大模型的 使用教程(AtomGit 限时开放) SEO关键词:GLM-5免费、Qwen3.5-398B免费API、AtomGit AI模型、免费大模型API、Qwen3.5接口调用、GLM5接口地址 最近在找一些可以免费调用的大模型 API时,意外发现一个平台开放了限时活动:AtomGit 提供 GLM-5、Qwen3.5 系列模型的免费调用,而且不限量。 https://atomgit.com/setting/points?type=invite&picode=RJFA9V4U&utm_source=ic_p 对于经常做 AI工具开发、自动化脚本、AI应用测试 的开发者来说,这种活动其实不太常见,所以简单记录一下注册和调用的方法,也顺便测试了一下实际情况。

By Ne0inhk
Synopsys:默认报告精度(report_default_significant_digits变量)

Synopsys:默认报告精度(report_default_significant_digits变量)

相关阅读 Synopsyshttps://blog.ZEEKLOG.net/weixin_45791458/category_12812219.html?spm=1001.2014.3001.5482         在使用report_timing之类的报告命令时,可以使用-significant_digits选项指定报告的精度,在不使用该选项的情况下,命令使用由report_default_significant_digits变量指定的默认精度进行报告。         对于不同的工具,该变量的默认值和取值范围略有差别,如下所示。 Design Compiler:默认值为-1(表示使用命令特定的默认值),取值范围为-1到13。 IC Compiler:默认值为-1(表示使用命令特定的默认值),取值范围为-1到13。 PrimeTime:默认值为2,取值范围为0到13。 PrimePower:默认值为2,取值范围为0到13。 Fusion Compiler:默认值为2,取值范围为0到13。 IC Compiler II:

By Ne0inhk
最新版 GLM-5 全栈实战全教程:从本地开源部署到 API 接入(多 Agent 架构 + 全栈编程 + 就业级项目实战)

最新版 GLM-5 全栈实战全教程:从本地开源部署到 API 接入(多 Agent 架构 + 全栈编程 + 就业级项目实战)

一、背景与技术概述 随着开源大模型技术的快速迭代,GLM-5 系列凭借优秀的指令遵循能力、长上下文支持、轻量化部署适配性与商用友好的开源协议,成为企业级AI落地与个人开发者技术进阶的核心选型之一。 本文以问题驱动为核心,完整覆盖从本地开源部署到工程化API封装、多Agent架构设计、全栈项目实战的全流程,解决开发者在大模型落地过程中面临的部署门槛高、工程化能力不足、Agent架构落地难、全栈项目缺乏可复用方案等核心痛点。本文所有实操步骤均经过生产环境验证,代码可直接复用,适配就业级项目的技术要求与企业落地标准。 1.1 GLM-5 核心技术特性 * 开源协议:Apache 2.0 协议,支持商用二次开发,无额外授权门槛 * 核心能力:支持128K超长上下文窗口,原生支持函数调用、多模态理解、结构化输出,指令遵循准确率较前代提升42% * 部署适配:原生支持FP8/INT4/AWQ/GPTQ多精度量化,最低可在16G显存环境完成流畅推理,适配消费级显卡与企业级GPU集群 * 性能优化:基于稀疏注意力架构与PagedAttention机制,推理吞吐量较同参数量模型提升3倍,

By Ne0inhk
zoxide 开源鸿蒙 PC 生态适配实战:Rust 交叉编译与 HNP 打包完整指南

zoxide 开源鸿蒙 PC 生态适配实战:Rust 交叉编译与 HNP 打包完整指南

zoxide 开源鸿蒙 PC 生态适配实战:Rust 交叉编译与 HNP 打包完整指南 前言:为什么要把 zoxide 引入开源鸿蒙 PC 生态? 作为 Linux 终端下广受欢迎的智能目录跳转工具,zoxide 凭借关键词模糊匹配 + 访问频率排序的核心优势,彻底解决了传统 cd 命令需记忆冗长路径、逐级跳转的痛点,成为开发者与运维人员提升终端效率的必备工具。随着鸿蒙PC生态的快速发展,终端命令行工具的丰富度成为提升用户体验的关键环节。为让开源鸿蒙 PC 用户也能享受到 zoxide 的高效便捷。 本文基于 Rust 交叉编译技术与开源鸿蒙 HNP 规范,详细拆解 zoxide 从源码拉取、构建脚本配置、交叉编译打包,到设备端安装验证的完整适配流程。文中不仅提供可直接复用的配置文件与命令代码,还汇总了适配过程中常见的 Rust 编译、链接器兼容等问题及解决方案,为开发者提供一套低成本、高可复用的开源鸿蒙

By Ne0inhk