初识typescript
Typescript算是最近比较流行的“语言”(强语言类型检测),有利于编写大型程序。strong typing貌似现在很多人比较认可。例如现在比较流行的Go以及新近的Kotlin。也是因为最近在使用antd而接触到,Angular2用的可能比较多。
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集(ES6的超集),而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
如果说只是简单的认为TS(Typescript以后用缩写TS来表示)是ES6的超集更趋进于ES8这种理解,在我看来是不对的。(原因后面再说 -。- 踩坑血泪史)。
为什么Typescript会火
前端发展的必然趋势
前端最近几年成井喷式发展,mvc、mvvm、mvp各种框架层出不穷,但是就是这种井喷式的发展给前端注入了一些新的活力,前端未来的发展趋势也是逐渐的趋于规范化,遥想当年java不也经历过这么一段“动荡”的时期么。而javascript本身就是一个弱语言无法和java这种强语言类型进行比较,但是一个强语言类型带来的优势又是如此的鲜明–健壮、易维护…(干嘛让我写这么全~我又不是搞java的-。-)那么问题来了怎么才能圆jser的这么一个梦想呢?Typescript!虽然我不能保证Typescript能够长久的活下去但是在我看来这个思路是对的!
实例
这里就不详细展开typescript的文档了,举个TS比较常用的例子。
interface TableProps<T>{
prefixCls?: string;
dropdownPrefixCls?: string;
rowSelection?: TableRowSelection<T>;
pagination?: PaginationProps | boolean;
size?: 'default' | 'small';
dataSource?: T[];
columns?: ColumnProps<T>[];
rowKey?: string | ((record: T, index: number) => string);
...
}
定义了一个TableProps接口规范–用来检测当前使用props是否符合规范,可以理解为React中的propTypes类型校验。其中还使用了<T>泛型。
如果想深入研究TS的话,可以直接访问Typescript官网,这里不做赘述。
实践
TS为了兼容jsx专门实现了tsx的文件,可以更方便的使用React。
使用ES6、ES7语法
当然babel已经可以解析ES6、ES7语法babel polyfill
,但是如果使用typescript的编译tsx/ts的时候使用的ts-loader
或者awesome-typescript-loader
,必须将tsconfig.json
lib添加需要的解析的语法,否则TS会检测出错。
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "es6",
"sourceMap": true,
"allowSyntheticDefaultImports": true,
"jsx": "react",
"lib": [
"dom",
"es2015.promise",
"es5",
"es2015.iterable",
"es2015.generator",
"es2015.symbol",
"es7"]
},
"exclude": [
"node_modules"
]
}
这个并不算完,因为这里设置target为ES6–编译后的js为ES6。如果需要编译成ES5那么ts将不会把ES6中 Generator
和ES7语法中的async await
编译成ES5。如果想将其编译成ES5的话那么就需要在loader中加入babel-loader。如:(使用webpack2语法)
{
test: /src\\pages(\\.*).(tsx|ts)/,
use: [
'bundle-loader?lazy',
'babel-loader',
'ts-loader',
],
},
同时typescript作者将在2.3 (May 2017) Generator support for ES3/ES5。
关于ts中全局变量/函数的定义及使用
使用场景:想在所有ts/tsx中引用一个辅助函数。(使用import太麻烦而且使用频率很高)。
解决方案(不完整):
1、webpack(Resolve alias)
创建全局变量别名,编写时直接引用,交给webpack解析。
2、发布一个npm,同时创建d.ts文件用来声明
@types/whatwg-fetch是使用的这种方案,编写中可以直接引用fetch,TS会检测到对应声明的d.ts文件,从而不会报错。
3、挂在到window
例如:encodechar -> 全局
创建一个global.d.ts文件,在其中声明declare const encodechar: string;
d.ts文件
这个算是一个小缺陷吧(这需要时间和积累),主流的框架或者插件是有@type的实现,但是很多小的框架是没有对应TS版本的,导致了很多小玩意在ts中玩不了,如果想玩需要用一些黑科技(自己声明一个d.ts版本….)举一个例子:
如果想使用import { bindActionCreator } from ‘redux’;
在TS检测是不通过的因为它没有实现bindActionCreator
的声明,所以一个黑暗的解决方案出现了,就是自己封装了一个bindActionCreator
同时写一个d.ts文件给TS进行识别。
弊端
说一下TS使用中的一些感觉不好的地方吧(用的比较浅显,纯属个人看法)。
1、d.ts文件要和js一样不断的进行同步迭代,否则会导致新加的接口报错。
2、增加了学习的复杂度,对于没有接触过C#,JAVA…来说,也是需要一点时间来接受的。
3、相对于React来说有点重合(纯属个人看法),因为React中也有props的类型检测,当然TS是一个全局的检测,不是一个量级的。
4、国内没有大范围使用,如果踩坑十分痛苦。
5、另外再说一下antd
和tsx
结合使用稍微会比jsx痛苦一点。(有些d.ts文件没有跟上迭代)例如:
antd V2.6.3
在Pagination.d.ts中
showTotal?: (total: number) => React.ReactNode;
没有第二个参数,但是源码中是有的。所以如果想使用只能人工添加TS才不会报错
showTotal?: (total: number, range?: [number,number]) => React.ReactNode;