鸿蒙中 TypeScript 与 ArkTS

620 阅读4分钟

TypeScript 与 ArkTS 的混合使用

首先,我们要知道一件事,鸿蒙应用开发,并一定需要所有的代码都使用 ArkTS 完成;官方 FAQ 里有一段这样的描述:developer.huawei.com/consumer/cn…

ArkTS基于兼容了TS语法,继承了TS的所有特性,当前,ArkTS在TS的基础上主要扩展了声明式UI能力,让开发者能够以更简洁、更自然的方式开发高性能应用。推荐用ArKTS开发UI相关内容,TS可以用来开发业务逻辑相关内容。

ts文件不支持调用ets文件中定义的方法。

ets调用ts文件中定义的方法,可以使用ES6中import引入及export导出的语法,将ts文件中的方法进行export导出,在ets文件中import引入该方法进行调用。

在实际的开发中,我们也发现 ArkTS 的限制也比 TypeScript 来的多:developer.huawei.com/consumer/cn…

结合上述 2 个背景,我们是可以在 UI 层的代码(ets)中引入一些使用 ts 实现的具体逻辑,具体一个case:

// assign.ts 
// 实现一个对象合并操作,由于 ArkTS 更加严格的要求该段代码在 ets文件下会报错
export function assign<T>(target: T, ...source: T[]): T {
  for (const items of source) {

    const entries = Object.entries(items)
    for (const entry of entries) {
      target[entry[0]] = entry[1]
    }
  }
  return target;
}

// Index.ets
import { assign } from './assign';


interface IModal {
  title: string;
  content?: string;
  onOk?: () => void
}

class Modal implements IModal {
  title: string = ''
  content?: string
  onOk?: () => void;
}


function info(title: string, options?: IModal) {
  if (options) {
    const data = assign<IModal>(options, { title });
    show(data);

  } else {
    show({ title })
  }
}

function show(options: IModal) {
  console.log(JSON.stringify(options));
}

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('1').onClick(() => {
        info('hello');
      })
      Text('2').onClick(() => {
        const a = new Modal()
        a.title = 'title'
        a.content = 'content';
        a.onOk = () => {
          console.log('onOk');
        }
        info('hello', a)
      })
      Text('3').onClick(() => {
        info('hello', {
          title: 'title',
          content: 'content',
          onOk() {
            console.log('onOk');
          },
        });
      })
    }.width('100%').height('100%')
  }
}

混合开发中 TS 中的 interface 和 abstract 的实际应用场景

在 TypeScript 中,interfaceabstract 都是用于定义类的结构或契约,但是它们的应用场景和目的有所不同。

Interface(接口)

用途:

  • 定义对象的形状:接口可以用来定义一个对象应该具有哪些属性和方法,以及这些属性和方法的类型。这有助于确保代码的一致性和可预测性。
  • 作为函数参数的类型:接口可以用来定义函数接收的参数的结构,从而确保传入的对象符合预期。
  • 实现多态性:多个类可以实现同一个接口,每个类提供自己的实现方式,这有助于编写更加灵活和可扩展的代码。

实际应用场景:

  • API 数据模型:当从服务器获取数据时,可以使用接口来定义响应数据的结构,以确保数据按预期格式处理。
  • 组件配置:在前端框架中,如 React,可以使用接口来定义组件的 props 结构,保证传入组件的数据是正确的。
  • 服务或模块的契约:定义服务或模块的输入输出结构,确保不同部分之间的交互遵循预定义的规则。

Abstract(抽象类)

用途:

  • 定义基类:抽象类不能直接实例化,它通常用作其他类的基类。它可以包含抽象方法(没有实现的方法),子类必须实现这些方法。
  • 共享通用逻辑:抽象类可以包含一些已实现的方法,这些方法可以被所有子类继承和使用,减少重复代码。
  • 强制实现某些方法:通过定义抽象方法,可以确保所有子类都必须实现特定的行为。

实际应用场景:

  • 数据库操作:创建一个抽象的数据库访问层,定义一些基本的操作方法(如增删改查),不同的子类可以针对不同的数据库实现这些方法。
  • 图形绘制:定义一个抽象的图形类,其中包含绘图的基本方法(如 draw()),然后为具体的图形(如圆形、矩形)创建子类,每个子类实现自己的绘图逻辑。
  • 游戏开发:在游戏开发中,可以有一个抽象的“游戏角色”类,定义了所有角色都必须有的行为(如移动、攻击),而具体的角色类则实现这些行为的具体细节。

总结

  • Interface 更适合于定义对象的结构和行为规范,适用于需要描述对象形状或函数参数类型的场景。
  • Abstract 更适合于构建继承关系中的基类,特别是当你希望强制子类实现某些方法或者共享一些通用逻辑时。

根据你的具体需求选择合适的方式,有时候两者也可以结合使用,以达到最佳的设计效果。

个人理解:以组合的思想进行业务开发,我们通常会更喜欢使用 Interface;Abstract 通过我们会遇到本身基类有实现的时候,复用基类方法会考虑;