目录
采用Flow
采用typescript
项目迁移typescript
Flow 与 TypeScript简单对比
总结
首页 web前端 js教程 关于react项目静态类型检查方案

关于react项目静态类型检查方案

Jul 09, 2018 am 11:02 AM
javascript typescript

这篇文章主要介绍了关于react项目静态类型检查方案,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

为什么需要引入类型检查

JS作为一个弱类型语言,具有很大的灵活性,但是它的优点也是它的缺点,它很容易让我们忽视一些隐晦的逻辑,语法错误或数据类型错误,在编译期甚至运行时看上去都不会报错,但是可能会发生各种各样奇怪的和难以解决的bug。

function getPrice(x) {
  return x * 10;
}
getPrice('a23') // NaN
登录后复制
function getDefaultValue (key, emphasis) {
    let ret;
    if (key === 'name') {
      ret = 'GuangWong';
    } else if(key=== 'gender') {
      ret = 'Man';
    }else if(key ==='age'){
      ret = 18;
    } else {
       throw new Error('Unkown key ');
    }
    if (emphasis) {
      ret = ret.toUpperCase();
    }
    return ret;
  }
  
  getDefaultValue('name'); // GuangWong
  getDefaultValue('gender', true) // MAN
  getDefaultValue('age', true)
登录后复制

这是一个简单的函数,第一个参数 key 用来获得一个默认值。第二参数 emphasis 为了某些场景下要大写强调,只需要传入 true 即可自动将结果转成大写。

但是如果不小心将 age 的值写成了数字字面量,如果我调用 getDefaultValue('age', true) 就会在运行时报错。这个有可能是业务上线了之后才发生,直接导致业务不可用

除此以外,在工作中,我们也经常遇到过对象上的一个属性在n个模块之间传递之后变成了 undefined。以上是代码健壮性的问题,工作中比较头疼的另外一个问题是协作性问题:如何让一个别人提供的方法产出一个一目了然的文档?因为一个项目总会涉及到多人协作:同学 A 编写了函数 a(),而 同学 B 在调用函数 a() 的时候得一直撸着 API 文档才能知道 a() 需要什么参数,会返回什么参数。

而 同学 A 后续又改动了函数 a(),但是却忘记了更新文档,这时候新接手项目的 同学 C 看着 API 文档和函数 a() 一脸懵逼,问题浮出水面:团队协作中,提供的接口如何描述自身?

这其中涉及到的问题有:

1.接口如何描述自己的参数和返回值?
2.接口参数和返回值在无数需求迭代中改变了多次,而这个 API 对应的文档该如3.何更新?
4.数据格式如何描述?

为了解决上述诸多痛点,我们需要引入类型检查机制,所谓类型检查,就是在编译期尽早发现(由类型错误引起的)bug,又不影响代码运行(不需要运行时动态检查类型),使编写js具有和编写Java等强类型语言相近的体验,它可以:

  • 使得大型项目可维护

  • 提高效率,错误在编写代码时报错,而非编译阶段

  • 增强代码的可读性,可以做到代码即文档

  • 增强设计

采用Flow

Facebook出品的JavaScript静态类型检查工具,它可以部分引入,不需要完全重构整个项目,所以对于一个已有一定规模的项目来说,迁移成本更小,也更加可行

flow使用学习成本也相对比较低

  1. 全局安装flow命令行工具

npm install -g flow-bin
登录后复制
  1. 在项目根目录,创建.flowconfig文件

  2. 安装babel插件

npm install --save-dev babel-plugin-transform-flow-strip-types
登录后复制
  1. 在.babelrc文件中添加插件

{
  "presets": [ "es2015", "react", "stage-1" ],
  "plugins": [
        "react-flow-props-to-prop-types"
  ]
}
登录后复制
  1. 安装扩展(⇧⌘X):Flow Language Support

  2. 修改VS Code对JavaScript的默认配置

Code -> 首选项 -> 用户设置(⌘,)
搜索:javascript.validate.enable
修改为:"javascript.validate.enable": false

  1. 在项目中使用

在需要静态检查的文件头引入flow,如:

/* @flow */
function getPrice(x: number) {
  return x * 10;
}
getPrice('a23') // vscode 工具提示错误
登录后复制

3596645301-5b40e665d2f7b_articlex[1].png

采用typescript

TypeScript 被称是 JavaScript 的超集,是微软公司推出的一种静态代码检查的方案,在 JavaScript 上做了一层封装,封装出 TypeScript 的特性,当然最终代码可以编译为 JavaScript

1.静态类型

let num: number;
num = 'likely';
    
[ts] 不能将类型“"likely"”分配给类型“number”。
let num: number
登录后复制

2.函数表达
js写法

export const fetch = function (url, params, user) {
  // dosomething

  return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}
登录后复制

以上下是一个 JavaScript 的函数,不看方法内的写法我们完全不知道这个 API 会有哪些坑。

export const fetch = function (url: string | object, params?: any, user?: User): Promise<object | Error> {
  // dosomething

  return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}
登录后复制

上述 TypeScript 包含了很多信息,让我们很方便地知道该函数怎么调用

  • url 可能是 string 或 object 类型

  • params 是可以不传的,也可以传递任何类型

  • user 要求是 User 类型的,当然也是可以不传

  • 返回了一个 Promise,Promise 的求值结果可能是 object,也有可能是 Error

3.组件

export interface CouponProps { 
  coupons: CouponItemModel[]; 
}

export interface couponState {
    coupons: CouponItemModel[],
    page: number,
    size: number,
    state: number,  //可用优惠券
    hasMore: boolean,
    isLoading: boolean,
    loadedError: boolean,
}


class CouponContainer extends React.Component<CouponProps, couponState> {
}
登录后复制

上述组件我们可以清晰地知道一个组件有哪些属性,哪些方法,哪些属性是必传的,哪些是可选的,一目了然,真正做到了代码即文档

关于typescript还有很多其他特点,如类,接口,泛型等,具体可参考官方文档
https://www.typescriptlang.org/

项目迁移typescript

1.node
(1)使用npm安装:npm install -g typescript,当前项目使用了是v2.8.3
(2)2.2 tsconfig.json

{
  "compilerOptions": {
      "module": "commonjs",
      "target": "es5",
      "noImplicitAny": true,
      "sourceMap": true,
      "lib": ["es6", "dom"],
      "outDir": "dist",
      "baseUrl": ".",
      "jsx": "react",
      "paths": {
          "*": [
              "node_modules/*",
              "src/types/*"
          ]
      }
  },
  "include": [
      "src/**/*"
  ]
}
登录后复制

(3)将.js文件改为.ts
(4)结合 gulp 进行实时编译

var gulp = require(&#39;gulp&#39;);
var pump = require(&#39;pump&#39;);
var webpack = require(&#39;webpack&#39;);

var ts = require(&#39;gulp-typescript&#39;);
var livereload = require(&#39;gulp-livereload&#39;);
var tsProject = ts.createProject("tsconfig.json");

gulp.task(&#39;compile:tsc:server&#39;, function () {
  return gulp.src(&#39;src/server/**/*.ts&#39;)
      .pipe(tsProject())
      .pipe(gulp.dest(&#39;dist/server&#39;));
});
//将任务同步执行
var gulpSequence = require(&#39;gulp-sequence&#39;);
gulp.task(&#39;compile&#39;, gulpSequence(
  &#39;compile:tsc:server&#39;,
))


gulp.task(&#39;watch&#39;, [&#39;compile&#39;], function() {
  livereload.listen();

  gulp.watch([&#39;./src/server/**/*.ts&#39;], [&#39;compile:tsc:server&#39;]);
})
登录后复制
  1. react

可在 webpack 配置文件添加规则

{ 
    test: /\.tsx?$/, 
    enforce: &#39;pre&#39;,
    use: [
        {
            loader: "ts-loader"
        }
    ]
 },
登录后复制

3.遇到的问题
遇到的问题

  • 动态地为global添加属性

由于js灵活的风格,我们经常动态地为某一对象添加属性,但是typeScript是编译型语言,基本原则是先定义再使用,所以当我们像下面这么引用

global.testName = &#39;哈哈&#39;;
登录后复制

便会出现这样的错误

类型“Global”上不存在属性“testName”
登录后复制

解决方法

(1)将global强制转化为any类型

 (<any>global).testName = &#39;哈哈&#39;
    
(2)扩展原有的对象

  global.prototy.testName = &#39;哈哈哈&#39;

(3)使用.d.ts文件
登录后复制
declare namespace NodeJS {
 
  export interface Global {
    testName: string;
  }
}
登录后复制

网上很多方法是直接添加一个.d.ts文件即可,但是亲测无效,需要在引用文件引入该文件,如本项目在app.ts文件中引入了

/// <reference path="../types/custom.d.ts" />
登录后复制

Flow 与 TypeScript简单对比

1267804671-5b4179e2cc68d_articlex[1].png

总结

Flow或者TypeScript都是静态类型检查的优秀解决方案,能够给有类型检查需求的一定规模的项目带来实际收益。基于现有项目的情况,迁移 TypeScript 时间成本比较大,学习曲线相对陡峭,建议现有项目采用 Flow 方案,对于一些新的项目,可以采用 TypeScript

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

react 官网动画库(react-transition-group)的新写法

React-Reflux的基础介绍

以上是关于react项目静态类型检查方案的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

See all articles