为什么选择typescript?
强类型语言的优势
1.错误可以更早的暴露 编码阶段可以消灭一大部分异常,不必等到运行阶段
2.强类型的代码,更能提高效率,代码更智能,编码更准确
3.使用强类型的语言重构更加牢靠,删除某个成员,或者是修改某个成员名称,会立即报出错误,然后进行相应的修改
4.减少不必要的类型判断
JavaScript 是没有类型提示的。而 TypeScript 有灵活的类型系统,可以编码期检查并且增强代码的可读性还提供了 any 类型进行缓冲。
小程序对 TS 的支持
d.ts 文件对于 TypeScript 来说是很重要的东西 。它声明了对外暴露的方法和属性。而小程序官方对 TypeScript 的支持,开发所依赖的类型声明会随着官方API 发生变动时小程序本身 API 的 d.ts 文件也会自动更改,更加省力。
使用
首先更新微信开发者工具到最新版,在创建新项目时选择 TypeScript 语言。
创建后,我们可以看到项目里带上了 typings 库,以及 TypeScript 的配置文件 tsconifg。
事件
视图的事件,对应的类型笔者在 typings 中并没有看到有 Interface 定义,可以暂时用 any,然后自己再用 as 转一下 event 携带的数据的类型。
Page&Data
在 typing 中定义了 Page 对象
declare const Page: Page.PageConstructor
interface PageConstructor {
<
D extends IAnyObject, T extends IAnyObject & PageInstance
>(
options: PageInstance<D, T> & T
): void }
它支持 D 和 T 两个范型。
泛型D
从下面的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,可以用 AnyObject 代替 D 或者 T 即可。
interface PageInstanceBaseProps<
D extends IAnyObject = any
> {
data?: D
setData?<K extends keyof D>(
data: D | Pick<D, K> | IAnyObject,
callback?: () => void
): void
}
// "!" : 告诉编译器,data不可能为null或者undefined
同时,由于 setData 和 data 都被声明为可选项,使用时需要加上!,this.setData!({})
和 this.data!
。
用上 TypeScript 之后,官方的 API 都可以直接看参数和返回值的类型,就不需要去查文档猜测类型了。
Component 的 properties 如果传入的是对象,怎么声明对象里属性的类型?