TypeScript In ICE

3,482 阅读6分钟

注:图片来源于 Google Image

目录

  • TypeScript 是什么
  • 为什么要使用 TypeScript
  • 使用 TypeScript 编写 React 组件
  • 在 ICE 中如何使用 TypeScript
  • 已有项目如何迁移到 TypeScript

TypeScript 是什么

关于 TypeScript 是什么,应该大部分人都已经知道,其 官网 的定义如下:

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source.

翻译成中文即是:

TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。

拆分一下关键词简单通俗的理解如下:

  1. TypeScript 是 JavaScript 的 强类型 版本。
  2. 提供了 静态类型系统 和支持 最新的不断发展的 JavaScript 新特性
  3. 在编译期去掉类型和特有语法,生成 纯粹的 JavaScript 代码
  4. 由于最终在浏览器中运行的仍然是 JavaScript,所以 TypeScript 并不依赖于浏览器的支持,也并不会带来兼容性问题。

为什么要使用 TypeScript

先来看一组数据:

TypeScript 月下载量

数据来源:npm 包下载量


Developer Survey Results 2018

数据来源:stackoverflow


TypeScript's Popularity Over Time

数据来源:StateOfJs 2018

从上面的数据来看,TypeScript 毫无疑问是当下非常受喜爱的编程语言。通过上述 TypeScript 的定义,我们知道 TypeScript 的核心是基于 JavaScript 弱类型 的特性提供了 静态类型系统。JavaScript 是一门弱类型语言,变量的数据类型具有动态性,可以被改变,只有在执行时才能确定变量的类型,这意味着有些错误只有在运行时才会发生。而 TypeScript 提供的类型机制则可以在编译时有效的解决这类问题,在编译时就暴露问题;同时基于类型定义加上 IDE 的智能提示,在开发和阅读代码时会非常的方便。在选择使用 TypeScript 时,你可以享受它带来的以下特性:

TypeScript 特性

  • 静态类型检查 :静态类型可以帮助我们在运行前发现潜在的未知问题,当你调用函数时,编辑器会提示参数类型,那些参数是可选的等等,以下代码在编译时也会直接编译失败,可以让我们在开发阶段感知错误。

  • IDE 提示功能 :增强了编辑器和 IDE 的功能,包括代码补全,接口文档提示,快速跳转等。

  • **可读性:**通过类型定义,代码之间的关系相对明确,使代码更容易阅读和理解,整个应用都是基于类型定义,也使协作变得更为方便和高效,类型就是最好的注释,本质上相当于强制约定写了一份文档。

TypeScript 缺点

无论是框架还是技术的演进,事物往往都存在两面性,在无限接近好的一方面,也会有瑕疵的一方面,TypeScript 解决 JavaScript 弱类型问题的同时,也引入自身的一些复杂度;从学习成本来讲,需要理解诸如 Generics(泛型)、Interfaces(接口)、Enums(枚举) 等概念;从开发效率上来讲,在前期开发阶段需要多写一些类型定义代码,需要一定的适应期,但从长期可维护性来看这些多的开发时间是值得的;从工具上来看,工欲善其事必先利其器,需要了解周边的工具生态系统,当然这些也算不上缺点。

周边生态

  • 编辑器:TypeScripts 是微软制造,目前流行的编辑器 VSCode 也出自微软,两者有着非常好的结合
  • 插件市场:在 VSCode 插件市场搜索 TypeScript 可以看到非常多的基于 TypeScript 插件可以使用
  • 前端框架:
  • 类型声明包:类似 React、Lodash 等库都有提供 TS 类型声明。如果你使用 VSCode,可以安装 types-autoinstaller 插件,可以自动安装相应的类型文件
# Before
npm i react @types/react -S

=> 

# After
npm i react -S

使用 TypeScript 编写 React 组件

通过 TypeScript 写 React 组件,主要区别就是 Props 和 State 的定义,如下两种写法:

  • ES6 语法
import React from 'react';

class App extends React.PureComponent {
  state = {
    name: 'ice',
    age: 1,
  };

  render() {}
}

App.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
};
  • TypeScript 语法
import * as React from 'react';

interface IProps {
  name: string;
  age: number;
}

interface IState {
  name: string;
  age: number;
}

class App extends React.PureComponent<IProps, IState> {
  state = {
    name: 'ice',
    age: 1,
  };

  render() {}
}

在 ICE 中使用 TypeScript

近两年来 TypeScript 在前端社区的发展越来越火热,也有越来越多的应用采用 TypeScript 编写,与此同时,飞冰(ICE)也在积极的拥抱 TypeScript 社区。ICE 提供了基于 TypeScript 的基础模板,该模板将飞冰(ICE)本身的能力和 TypeScript 能力做了很好的融合:

  • 内置 @alifd/next 基础组件
  • 支持组件按需加载
  • 支持 css-modules 语法
  • 支持 TypeScript 语法
  • 支持热更新

你只需要在 Iceworks 模板界面选择对应模板进行初始化:

初始化完成之后,接下来就是使用 TypeScript 编写代码了,所有以 .tsx 或者 .ts 结尾的文件都支持其语法。

已有项目如何迁移到 TypeScript

迁移步骤如下:

  • 升级构建工具 ice-scripts
# ice-scripts 最新版支持 TypeScript 的语法构建
$ npm update ice-script
  • 项目安装 TypeScript 开发依赖
$ npm install typescript -D
  • 新增 .tsconfig 文件
{
  "compileOnSave": false,
  "buildOnSave": false,
  "compilerOptions": {
    "outDir": "build",      // 指定输出目录
    "module": "esnext",     // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
    "target": "es6",        // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
    "jsx": "react",        // 允许编译 javascript 文件
    "moduleResolution": "node", // 选择模块解析策略
    "allowSyntheticDefaultImports": true,
    "lib": ["es6", "dom"],
    "sourceMap": true,     // 生成相应的 '.map' 文件
    "allowJs": true,       // 扩展名可以是 .js/.jsx
    "noUnusedLocals": true // 有未使用的变量时,抛出错误
  },
  "include": ["src/*"],  // 需要编译的文件目录
  "exclude": ["node_modules", "build", "public"] // 排除编译的文件目录
}
  • 按需修改文件后缀

在 TypeScript 工程中推荐使用 .tsx 替代 .jsx、使用 .ts 替代 .js,这里可以根据自身需求按需更改,一般情况下更改后缀之后需要修改部分语法,否则 ts 语法检测可能会不通过。

  • 按需修改 Entry 入口

如果将 src/index.js 的后缀做了修改,那么同步需要修改 package.json 里的 entry 字段:

// packgae.json
buildConfig: {
-  entry: './src/index.js'
+  entry: './src/index.ts'
}

按照以上步骤,可按需迁移项目到 TypeScript 工程。如有疑问,请通过飞冰钉钉群联系我们。

资料

ICE 相关链接