什么是 TypeScript

TypeScript 简称 TS,是微软开发的 javascript 加强版,顾名思义就是带了 type 的 javascript。它的很多特性可以帮助我们写出更加健壮的代码,弥补 javascript 在开发大型项目时的先天不足。

TypeScript 允许你以 接口 的形式定义复杂的类型。当你要在应用程序中使用复杂的 对象或数组(例如包含其他属性的对象)时,会进行严格的静态类型审查,增加健壮性。

开始一个 demo

接下来让我们来使用 antd 开发一个功能完备的 crud 应用程序来带我们认识一下 TypeScript 的优越之处。在 umi 中内置了 TypeScript 的 Loader,你可以直接新建 .tsx 或者 .ts 文件来写 TypeScript 代码。demo 地址

首先我们安装依赖包

cnpm install tslint tslint-config-prettier tslint-react @types/react @types/react-dom --save

然后我们需要新建 tsconfig.jsontslint.json文件,tsconfig.json 来声明这是一个 TypeScript 项目,并且进行配置。详细配置可以参考官网,我们可以直接直接输入如下内容:

  1. {
  2. "compilerOptions": {
  3. "outDir": "build/dist",
  4. "module": "esnext",
  5. "target": "es2016",
  6. "lib": ["es6", "dom"],
  7. "sourceMap": true,
  8. "jsx": "react",
  9. "allowSyntheticDefaultImports": true,
  10. "moduleResolution": "node",
  11. "rootDir": "src",
  12. "forceConsistentCasingInFileNames": true,
  13. "noImplicitReturns": true,
  14. "suppressImplicitAnyIndexErrors": true,
  15. "noUnusedLocals": true,
  16. "experimentalDecorators": true
  17. },
  18. "exclude": [
  19. "node_modules",
  20. "build",
  21. "scripts",
  22. "acceptance-tests",
  23. "webpack",
  24. "jest",
  25. "src/setupTests.ts",
  26. "tslint:latest",
  27. "tslint-config-prettier"
  28. ]
  29. }

tslint 类似 eslint 是一个代码风格检查器。tslint.json我们可以直接使用如下配置:

  1. {
  2. "extends": ["tslint:latest", "tslint-react", "tslint-config-prettier"],
  3. "rules": {
  4. "no-var-requires": false,
  5. "no-submodule-imports": false,
  6. "object-literal-sort-keys": false,
  7. "jsx-no-lambda": false,
  8. "no-implicit-dependencies": false
  9. }
  10. }

为了增加使用体验,建议一并安装 vscode tslint 插件。

我们可以先做一个简单的 demo 来感受一下 TypeScript 的魅力。首先在 src/page 新建一个 Demo.tsx.
在其中定义一个无状态组件 Hello。

  1. import React from 'react';
  2. const Hello = ({ name }) => <div>Hello,{name}</div>;

接下来我们使用它,

  1. const App = () => <Hello />;
  2. export default App;

我们发现他抛出了如下错误 :

不能将类型“{}”分配给类型“{ name: any; }”。类型“{}”中缺少属性“name”。

因为我们使用了 name,Typescript 认为他是必填参数。如果不存在便认为程序错误,并造成编译失败。这可以帮助我们避免很多低级错误。

我们还可已将 name 使用 SFC 进一步约束,规定 name 为 string 类型,来增加健壮性。

  1. const Hello: React.SFC<{ name: string }> = ({ name }) => (
  2. <div>Hello,{name}</div>
  3. );

我们也可以使用 Class 语法来声明组件,代码如下:

  1. class Message extends React.Component<{
  2. message: string;
  3. }> {
  4. public render() {
  5. return <div>{this.props.message}</div>;
  6. }
  7. }

我们可以通过 <> 的第一个参数来指定 props 的类型。通过第二个参数来指定 state 的类型,代码如下:

  1. class Message extends React.Component<
  2. {
  3. message: string;
  4. },
  5. {
  6. count: number;
  7. }
  8. > {
  9. constructor(props) {
  10. super(props);
  11. this.state = {
  12. count: 0,
  13. };
  14. }
  15. public render() {
  16. return (
  17. <div>
  18. {this.props.message}
  19. {this.state.count}
  20. </div>
  21. );
  22. }
  23. }

在这里,我们定义了一个 包含 count 的 state ,count 的类型为 number。然后在类 constructor 内部初始化 state。其余使用方式与 javascript 中相同。

我们可以自行修改 count,

  1. public increment = () => {
  2. const { count } = this.state;
  3. this.setState({
  4. count: count + 1
  5. });
  6. };

并且将其绑定到 dom 上,

  1. public render() {
  2. return (
  3. <div onClick = {this.increment}>
  4. {this.props.message}
  5. {this.state.count}
  6. </div>
  7. );
  8. }

使用 Message 组件:

  1. const App = () => <Message message="点击"/>;
  2. export default App;