鸿蒙从入门 TypeScript 知识储备:函数

鸿蒙(HarmonyOS)是华为公司自主研发的一款面向全场景的分布式操作系统。它于2019年8月9日在华为开发者大会上首次亮相,2020年9月10日正式发布2.0版本。
主要特点:
- 分布式架构:支持设备间无缝协同
- 微内核设计:安全性更高
- 跨设备开发:一次开发,多端部署
- 低时延:响应速度更快
发展历程:
- 2019年:发布1.0版本
- 2020年:推出2.0版本
- 2021年:升级至3.0版本
- 2022年:发布4.0版本
应用场景:
- 智能家居
- 智能办公
- 智能出行
- 运动健康
- 影音娱乐
技术优势:
- 分布式数据管理
- 设备虚拟化能力
- 多设备连接协同
- 原子化服务
目前鸿蒙系统已应用于华为手机、平板、智能手表、智慧屏等多种设备,并逐步扩展至汽车、家电等领域。截至2023年,鸿蒙生态设备数量已超过3亿台。
函数基础概念
在 TypeScript 中,函数是执行特定任务的可重用代码块,是构建应用程序的重要基础。与 JavaScript 类似,TypeScript 函数提供了参数类型检查和返回值类型定义的能力,这为开发者带来了更强的类型安全保障。
TypeScript 函数的主要特点包括:
-
类型注解:可以为函数参数和返回值指定类型,例如:
function greet(name: string): string { return `Hello, ${name}!`; } -
可选参数和默认参数:
function createUser(name: string, age?: number, isAdmin: boolean = false) { // 函数体 } -
剩余参数:使用
...语法处理可变数量的参数:function sum(...numbers: number[]): number { return numbers.reduce((acc, curr) => acc + curr, 0); } -
函数重载:允许定义多个函数签名来支持不同的参数组合:
function configure(config: string): void; function configure(config: object): void; function configure(config: any) { // 实现逻辑 } -
箭头函数:提供更简洁的语法:
const double = (x: number): number => x * 2;
在实际开发中,TypeScript 函数常用于:
- 业务逻辑封装
- 数据处理和转换
- 事件处理
- 作为高阶函数的参数或返回值
通过 TypeScript 的类型系统,开发者可以在编译阶段就发现潜在的类型错误,大大提高了代码的可靠性和可维护性。
函数声明与调用
// 函数声明
function greet(name: string): string {
return `Hello, ${name}!`;
}
// 函数调用
const greeting = greet("鸿蒙开发者"); // 返回 "Hello, 鸿蒙开发者!"
函数参数
TypeScript 函数支持多种参数类型:
- 必需参数:调用时必须提供的参数
- 可选参数:使用
?标记 - 默认参数:为参数提供默认值
- 剩余参数:使用
...语法收集多个参数
// 可选参数与默认参数
function buildName(firstName: string, lastName?: string, title: string = "Mr."): string {
return `${title} ${firstName} ${lastName || ""}`.trim();
}
// 剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
函数类型
函数类型注解
TypeScript 允许为函数定义类型:
// 函数类型表达式
type GreetFunction = (name: string) => string;
// 使用接口定义函数类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
箭头函数
箭头函数提供更简洁的语法:
// 普通函数
const square = function(x: number): number {
return x * x;
};
// 箭头函数
const squareArrow = (x: number): number => x * x;
// 箭头函数在鸿蒙应用中的典型使用场景
const button = new Button();
button.onClick(() => {
console.log("按钮被点击了");
});
高级函数特性
函数重载
TypeScript 支持函数重载,允许定义多个函数签名:
// 函数重载示例
function getDeviceInfo(deviceId: string): DeviceInfo;
function getDeviceInfo(deviceId: string, includeDetails: boolean): DetailedDeviceInfo;
function getDeviceInfo(deviceId: string, includeDetails?: boolean): DeviceInfo | DetailedDeviceInfo {
// 实现代码
}
泛型函数
泛型函数可以处理多种数据类型:
// 泛型函数示例
function identity<T>(arg: T): T {
return arg;
}
// 在鸿蒙UI开发中的应用
function createComponent<T extends Component>(componentType: new () => T): T {
return new componentType();
}
函数在鸿蒙开发中的应用
UI事件处理
// 按钮点击事件处理
@Entry
@Component
struct MyComponent {
private count: number = 0;
build() {
Button("点击我")
.onClick(() => {
this.count++;
console.log(`按钮被点击了${this.count}次`);
})
}
}
API调用封装
// 封装网络请求函数
async function fetchData<T>(url: string, method: "GET" | "POST" = "GET", data?: any): Promise<T> {
try {
const response = await http.request({
url,
method,
data
});
return response.data as T;
} catch (error) {
console.error("请求失败:", error);
throw error;
}
}
// 使用示例
interface UserData {
id: number;
name: string;
}
const user = await fetchData<UserData>("https://api.example.com/users/1");
工具函数开发
// 防抖函数实现
function debounce<T extends (...args: any[]) => any>(func: T, delay: number): T {
let timer: number | null = null;
return function(this: any, ...args: any[]) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
} as T;
}
// 在鸿蒙应用中使用
const searchInput = new TextInput();
searchInput.onChange(debounce((value: string) => {
console.log("搜索:", value);
// 执行搜索逻辑
}, 300));
最佳实践
- 明确参数和返回值类型:始终为函数参数和返回值指定类型
- 合理使用可选参数:避免过多可选参数,考虑使用对象参数
- 保持函数单一职责:每个函数应该只做一件事
- 适当使用函数重载:当函数有多种调用方式时
- 考虑性能影响:避免在渲染函数中执行复杂计算
// 好的实践示例
interface UserOptions {
name: string;
age?: number;
isAdmin?: boolean;
}
function createUser(options: UserOptions): User {
// 实现代码
}
// 使用
const user = createUser({
name: "张三",
age: 25
});
HarmonyOS开发常见问题
基础环境配置问题
-
DevEco Studio安装失败
- 可能原因:系统环境不满足最低要求(至少Windows 10 64位/Ubuntu 18.04/macOS 10.14)、JDK版本不兼容(需要JDK 1.8)或磁盘空间不足(至少8GB)
- 解决方案:检查系统版本,确保安装正确的JDK版本,清理磁盘空间
-
SDK下载速度慢
- 可使用国内镜像源加速下载,修改DevEco Studio的SDK Manager配置中的下载地址为国内镜像站
-
模拟器无法启动
- 常见于Windows系统,需检查是否已开启Hyper-V或Windows Hypervisor Platform(WHPX),在BIOS中确保虚拟化技术已启用
应用开发常见问题
-
Ability生命周期管理
- 常见误区:未正确处理onBackground和onForeground回调,导致资源未及时释放
- 示例场景:音乐播放器应用切换时,应在onBackground暂停播放,onForeground恢复播放
-
UI布局适配问题
- HarmonyOS支持多种设备类型,需要使用响应式布局
- 推荐使用DirectionalLayout和DependentLayout进行布局设计
- 典型问题:固定像素值导致不同设备显示效果差异
-
权限申请失败
- 常见于需要敏感权限(如位置、相机)的应用
- 必须先在config.json中声明权限,再动态申请
- 用户拒绝后应有优雅降级处理方案
分布式能力问题
-
设备发现失败
- 检查设备是否登录相同华为账号
- 确保设备在同一局域网内
- 验证是否已正确实现IDiscoveryCallback接口
-
分布式数据同步延迟
- 大数据量传输推荐使用分块传输策略
- 网络不稳定时应有重试机制
- 可考虑使用KVStore的本地缓存策略
-
跨设备调用性能问题
- 避免频繁的小数据量跨设备调用
- 复杂业务逻辑建议在本地处理
- 使用分布式任务调度时注意任务优先级设置
调试与性能优化
-
日志查看困难
- 熟练使用hilog命令行工具
- 建议开发阶段设置不同的日志级别
- 关键业务流程添加详细的日志输出
-
内存泄漏排查
- 使用DevEco Studio的内存分析工具
- 特别注意Ability和Service的引用关系
- 常见泄漏点:未注销的事件监听器
-
启动时间优化
- 减少主线程的耗时操作
- 合理使用异步任务
- 复杂初始化操作可延迟执行
发布与上架问题
-
应用签名失败
- 确保使用正确的签名证书
- 检查签名文件路径是否包含中文或特殊字符
- 验证签名配置是否与AppGallery Connect一致
-
审核被拒常见原因
- 隐私政策不完善
- 权限使用说明不清晰
- 未适配深色模式
- 目标API版本过低
-
版本更新问题
- 注意保留旧版本兼容性
- 重大更新建议提供过渡期
- 回滚机制应考虑数据兼容性
TypeScript常见问题详解
类型系统相关
1. 类型推断与类型断言的区别
类型推断是TypeScript自动根据赋值推断变量类型的能力:
let num = 42; // TypeScript推断num为number类型
类型断言是开发者明确告诉TypeScript变量类型的方式:
let someValue: any = "this is a string";
let strLength1: number = (<string>someValue).length; // 尖括号语法
let strLength2: number = (someValue as string).length; // as语法
应用场景对比:
- 类型推断适用于简单明显的类型赋值
- 类型断言适用于处理联合类型或any类型时明确具体类型
2. 接口与类型的区别
接口(interface):
- 主要用于定义对象形状
- 支持声明合并
- 更适合用于类实现
示例:
interface Person {
name: string;
age: number;
greet(): void;
}
class Student implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}
类型别名(type):
- 可以定义任何类型,包括原始类型、联合类型、元组等
- 不支持声明合并
- 可以使用条件类型、映射类型等高级特性
示例:
type ID = string | number;
type Coordinates = [number, number];
type Tree<T> = {
value: T;
left?: Tree<T>;
right?: Tree<T>;
};
选用建议:
- 优先使用接口定义对象结构
- 当需要联合类型、元组或复杂类型时使用类型别名
编译与配置
3. tsconfig.json常见配置问题
关键配置项详解:
-
compilerOptions.target:
- 指定编译后的JS版本(ES3, ES5, ES6/ES2015等)
- 示例:
"target": "ES2018"
-
compilerOptions.module:
- 指定模块系统(CommonJS, ES6, AMD等)
- 示例:
"module": "CommonJS"(Node.js环境常用)
-
compilerOptions.strict:
- 启用所有严格类型检查选项
- 包括:noImplicitAny, strictNullChecks等
-
paths配置别名:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@utils/*": ["src/utils/*"]
}
}
}
常见错误解决方案:
- 找不到模块:检查
baseUrl和paths配置 - 类型检查不严格:启用
strict系列选项 - 编译速度慢:配置
exclude排除node_modules
开发实践
4. 如何处理第三方库类型定义
三种情况处理方案:
-
库自带类型定义:
- 直接安装即可,TypeScript会自动识别
- 示例:
lodash、react等主流库
-
需要单独安装类型定义:
- 使用
@types/前缀安装 - 示例:
npm install --save-dev @types/jquery
- 使用
-
没有类型定义的库:
- 创建declaration文件(如
src/types/global.d.ts)
declare module 'untyped-library' { const lib: any; export default lib; }- 或使用
// @ts-ignore临时忽略
- 创建declaration文件(如
5. 类型保护与类型收窄
四种常用类型保护方法:
- typeof类型保护:
function padLeft(value: string | number) {
if (typeof value === 'number') {
return value.toFixed(2); // 此处value确定为number
}
return value.padStart(10); // 此处value确定为string
}
- instanceof类型保护:
class Bird { fly() {} }
class Fish { swim() {} }
function move(pet: Bird | Fish) {
if (pet instanceof Bird) {
pet.fly();
} else {
pet.swim();
}
}
- 自定义类型谓词:
interface Cat { meow(): void; }
interface Dog { bark(): void; }
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function handleAnimal(animal: Cat | Dog) {
if (isCat(animal)) {
animal.meow();
} else {
animal.bark();
}
}
- 可辨识联合:
interface Square {
kind: "square";
size: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Circle;
function area(shape: Shape) {
switch (shape.kind) {
case "square": return shape.size ** 2;
case "circle": return Math.PI * shape.radius ** 2;
}
}
高级类型
6. 实用工具类型应用
常用工具类型及示例:
- Partial<T>:使所有属性变为可选
interface User {
id: number;
name: string;
age: number;
}
type PartialUser = Partial<User>;
// 等效于 { id?: number; name?: string; age?: number; }
- Required<T>:使所有属性变为必需
type RequiredUser = Required<PartialUser>;
// 还原为原始User接口
- Pick<T, K>:选择部分属性
type UserNameAndAge = Pick<User, 'name' | 'age'>;
// { name: string; age: number; }
- Omit<T, K>:排除部分属性
type UserWithoutAge = Omit<User, 'age'>;
// { id: number; name: string; }
- Record<K, T>:创建键值类型
type PageInfo = {
title: string;
};
type Page = 'home' | 'about' | 'contact';
const nav: Record<Page, PageInfo> = {
home: { title: 'Home' },
about: { title: 'About' },
contact: { title: 'Contact' }
};
常见错误与解决方案
7. 类型兼容性问题
典型错误示例与修复:
- 对象字面量额外属性检查:
interface Config {
width: number;
height: number;
}
// 错误:对象字面量只能指定已知属性
const config: Config = {
width: 100,
height: 200,
color: 'red' // 报错
};
// 解决方案1:使用类型断言
const config1: Config = {
width: 100,
height: 200,
color: 'red'
} as Config;
// 解决方案2:使用索引签名扩展接口
interface Config {
width: number;
height: number;
[propName: string]: any;
}
- 函数参数类型不兼容:
interface Handler {
(name: string, age: number): void;
}
// 错误:参数类型不匹配
const handler: Handler = (userName: string, userAge: number, isAdmin: boolean) => {
// ...
};
// 解决方案:使用函数重载或调整接口定义
interface ExtendedHandler {
(name: string, age: number, isAdmin?: boolean): void;
}
8. 模块导入导出问题
常见模块问题及解决:
- 默认导入与命名导入混淆:
// 模块导出方式
export default function greet() { /*...*/ }
export const version = '1.0';
// 正确导入方式
import greet, { version } from './module';
// 错误示例
import { greet } from './module'; // 报错
- CommonJS模块导入:
// 正确导入方式
import * as fs from 'fs'; // ES6语法
import fs = require('fs'); // TypeScript语法
const fs = require('fs'); // 需要启用allowSyntheticDefaultImports
// 配置建议:在tsconfig.json中设置
{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}
- 动态导入:
// 使用import()函数实现动态导入
async function loadModule() {
const module = await import('./someModule');
module.doSomething();
}
// 类型安全的动态导入
interface SomeModule {
doSomething(): void;
version: string;
}
async function loadTypedModule() {
const module = await import('./someModule') as SomeModule;
module.doSomething();
}
更多推荐


所有评论(0)