微信小程序 TypeScript 尝试

栏目: IOS · Android · 发布时间: 5年前

内容简介:自从去年开始在项目里写了一段时间 Javascript 后,感觉没有类型检查的语言还是不太适合我,所以一直想尝试下 TypeScript,然而由于项目庞大,人员协作问题,一时半会没办法切成 TypeScript。正好最近有小程序的需求和小程序去年 11 月开始官方支持了 TypeScript,所以拿来练练手。大概是我这半年写的 Swift 比较多,而 Swift 中的静态类型和协议是我很喜欢的特性。正好 TypeScript 为 JavaScript 带来了“动态类型一时爽,代码重构火葬场“,对于我这种极度

自从去年开始在项目里写了一段时间 Javascript 后,感觉没有类型检查的语言还是不太适合我,所以一直想尝试下 TypeScript,然而由于项目庞大,人员协作问题,一时半会没办法切成 TypeScript。正好最近有小程序的需求和小程序去年 11 月开始官方支持了 TypeScript,所以拿来练练手。

Why TypeScript?

大概是我这半年写的 Swift 比较多,而 Swift 中的静态类型和协议是我很喜欢的特性。正好 TypeScript 为 JavaScript 带来了 静态类型接口

可选的静态类型

“动态类型一时爽,代码重构火葬场“,对于我这种极度喜欢重(xia)构(gai)代码的人来说,JavaScript 毫无类型提示,类型全靠命名猜测是极度不友好的。而 TypeScript 加上了灵活的类型系统,不仅可以编码期检查,还能增强代码的可读性,并提供了 any 类型进行缓冲。

接口

接口和协议,只是不一样的叫法而已,Java、C#、TypeScript 叫 Interface,Swift、Kotlin 叫 Protocol,就是一种规则声明。项目中,和后端接口数据交互,页面传递数据,数据持有,方法代理的地方,有了接口就会更加方便,易重构。TypeScript 的 Interface + JavaScript 简单的对象就让数据构建变得简单又不容易出错。

小程序对 TypeScript 的支持

TypeScript 有一个很重要的东西,就是 d.ts 文件。d.ts 文件其实相当于 C 系语言里面的 .h 头文件,声明了对外暴露的方法和属性。而小程序官方对 TypeScript 的支持,意味着官方会维护小程序本身 API 的 d.ts 文件,也就是 typing 库,这样当 API 发生变动时,就可以即时变更。

使用也很简单,更新微信开发者 工具 到最新版,在创建新项目时选择 TypeScript 模板。

微信小程序 TypeScript 尝试

创建后,我们可以看到项目里带上了 typings 库,以及 TypeScript 的配置文件 tsconifg。之后,保存时就不会自动编译了,要点击小程序工具栏的编译按钮才可以。

这里有一个坑,笔者电脑安装的 TypeScript 版本是 3.2.2 版本。编译时会被找不到全局类型 CallableFunction 和 NewableFunction。

微信小程序 TypeScript 尝试

解决方法也很简单,到 node_modules 路径下的 TypeScript 包的 bin 目录下,lib.es5.d.ts 文件里面把这两个类型的 Interface 拷贝到,小程序 typing 目录下的 lib.wa.es6.d.ts 里面就可以了。小程序模板里这个文件应该是拷贝 TypeScript 官方的,但没有随着官方升级而改变。

事件

视图的事件,对应的类型笔者在 typings 中并没有看到有 Interface 定义,所以只能暂时用 any,然后自己再用

as 转一下 event 携带的数据的类型。

Page&Data

每个 Page 对象,在 typing 里是这么定义的。

declare const Page: Page.PageConstructor

interface PageConstructor {
    <D extends IAnyObject, T extends IAnyObject & PageInstance>(
      options: PageInstance<D, T> & T
    ): void
  }
复制代码

也就是说,它支持 D 和 T 两个范型。这两个范型是什么呢?小程序里,Page 是这么写的。

Page({});
复制代码

也就是说,options 参数就是一个 PageInstance,范型也被传入了。

interface PageInstance<D extends IAnyObject = any, T extends IAnyObject = any> extends PageInstanceBaseProps<D>
复制代码

PageInstance 里面定义了 Page 声明周期的方法,而且继承自 PageInstanceBaseProps,并将范型 D 传入。

interface PageInstanceBaseProps<D extends IAnyObject = any> {
    data?: D
    //...
}
复制代码

所以这个 D 范型,其实就是 data 的类型接口。因为 data 不是必须实现的,所以这里是可选型 ?。

那么 T 是什么呢?

T extends IAnyObject & PageInstance
复制代码

T 其实就是对 PageInstance 的拓展,PageInstance 是 Page 的实例接口,那么 T 其实就是在 Page 里面 this 的类型接口了,也就是说,需要在 Page 里新增的方法和属性,都在 T 里定义。

所以,对于一个普通页面我们可以声明两个接口,一个代表 data, 一个代表 page,举个例子。

interface IIntroPage {
	nextButtonTap(event: any): void;
    isLoading: boolean;
}

interface IIntroData {
    test: string;
}

Page<IIntroData, IIntroPage>({
    isLoading: false,
	nextButtonTap(event: any) {
        this.isLoading = true;
	}
});
复制代码

如果这个页面不需要 data 或者不需要扩展 page,用 IAnyObject 代替 D 或者 T 即可。

interface PageInstanceBaseProps<D extends IAnyObject = any> {
    data?: D
    setData?<K extends keyof D>(
      data: D | Pick<D, K> | IAnyObject,
      callback?: () => void
    ): void
}
复制代码

同时,由于 setData 和 data 都被声明为可选项,使用时需要加上!, this.setData!({})this.data!

其他就没什么了,用上 TypeScript 之后,官方的 API 都可以直接看参数和返回值的类型,再也不用去查文档猜测类型了。

调用 JavaScript

为 JavaScript 编写一个简单的 .d.ts 文件,将需要调用的类和方法暴露出来。详情见如何编写一个d.ts文件。

最后

虽然笔者用了 TypeScript 不久,但严格的检查的确让我在增删改接口字段能快速全局重构,而且方法调用联想,API 查看也方便了不少。小程序对 TypeScript 的支持日常使用开发是没有什么问题了,就是官方的文档指引比较少。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning Vue.js 2

Learning Vue.js 2

Olga Filipova / Packt Publishing / 2017-1-5 / USD 41.99

About This Book Learn how to propagate DOM changes across the website without writing extensive jQuery callbacks code.Learn how to achieve reactivity and easily compose views with Vue.js and unders......一起来看看 《Learning Vue.js 2》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换