微信小程序 TypeScript 尝试

自从去年开始在项目里写了一段时间 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 模板。

屏幕快照 2019-01-30 下午8.51.40

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

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

image-20190130195121996

解决方法也很简单,到 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 的支持日常使用开发是没有什么问题了,就是官方的文档指引比较少。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 155,348评论 4 355
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 65,906评论 1 283
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,191评论 0 235
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,295评论 0 201
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,606评论 3 283
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,107评论 1 202
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,507评论 2 305
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,217评论 0 193
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,848评论 1 234
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,183评论 2 238
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,734评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,084评论 2 247
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,608评论 3 228
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,921评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,627评论 0 190
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,103评论 2 261
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,054评论 2 257

推荐阅读更多精彩内容