flow

// 一:
// 在flow中如果想要为一个数据添加类型
// 1. 通过注释的方式进行添加
// 2. 通过直接改写js代码结构(推荐)

// 需要给文件添加@flow标记,否则flow不会对文件进行类型检测

// @flow
var a /*: number*/ = 10; //方式一   //正常使用
var a: number = 10; //方式2     //需要babel进行转码

a = "abc"; //检查会出错
console.log(a);

function sum(a: number, b: number) {
    return a + b
}
console.log(sum("2", 2))


// 二.类型种类
//1, number类型
// number类型可以赋值的内容为: 数字、NaN、Infinity
let a: number = 100;
let b: number = NaN;
let c: number = Infinity;

//2, string类型
// string类型可以赋值的内容为: 字符串
let str: string = "abc";

//3, boolean 布尔值类型
//4, void  javascript中的undefined   //当函数不返回时是void
//5, null  js中的null

//6, Array类型
// 在声明数据为数组类型的时候,我们需要为数组指定元素的类型
let arr: Array < number > = [1, 2, 3, 4]; //数组需要加<>

let name: any = 123; //any 是任何类型都可以
name = "123"

let arr1: Array < any > = [1, 'a', {},
    []
];

//7, Maybe类型相当于给数据添加了两个可能的类型null和void
function test(a: ? number) { //?  maybe类型
    a = a || 0;
    console.log(a);
}
test(10);
test();

//8, 或类型  自动推断操作
let a: number | string = 10;
a = "abc";
a = {};

function test(a: number, b: number) { // 类型推断
    return a + b;
}
let c: string = test(1, 2); //这里会报错,能推断返回值为number类型

//9, 函数类型
function test(a: number, b: number): number {
    return a + b;
}
var a: string = test(1, 2);
// 可以将变量声明为函数类型
// 也就意味着我们可以指定为变量赋值的函数的类型
let func: (a: number, b: number) => string = test;

function ajax(callback: (data: Object) => void) {

}
ajax(function(obj: Object) {})

//10, 对象类型
function greet(obj: { sayHello: () => void, name: string }) {
    obj.sayHello();
}
var o = {
    name: "张学友",
    sayHello() {
        console.log("Hello")
    }
}
greet(o);

function ajax(option: { url: string, type: string, success: (data: Object) => void }) {}
// option需要有url参数,还需要有type参数 还需要有success参数
ajax({});


// 三,使用步骤
Flow的基本使用步骤

# FLOW是 JAVASCRIPT的静态类型检查器

地址: https: //flow.org/
    安装
npm init - y
npm i flow - bin - D //开发依赖

书写代码, 为代码添加类型

var 变量: 数据类型 = 数据;

1. 通过注释的方式添加(不会改写js代码, 代码在添加完类型之后仍然可以正常运行)
2. 通过直接给数据添加类型, 改写js代码, 如果要正常运行, 需要使用babel进行转码

## 使用flow进行类型检查
0, 在pacakge.json文件中, scripts属性中添加flow命令
    // 
    "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "flow": "flow",
        "build": "babel ./src -d ./dist"
    },

    1. 需要为flow创建一个配置文件.flowconfig //项目根目录
npm run flow init

2, .flowconfig文件中意思
    [ignore] //   要忽略的文件
    [include] //包含的检查文件
    [libs] //第三方库
    [lints] //代码实时校验
    [options]
    [strict] //都不写默认对所有文件进行检测

3. 执行类型检查
npm run flow

使用babel对flow代码进行转码
如果给数据添加类型声明是通过第二种方式, 直接修改的js代码, 那么代码是不能正常运行的

我们需要通过babel对代码进行转码之后才能正常运行

1. 安装babel以及presets
npm i babel - cli babel - preset - flow - D

{
    "presets": [ //.babelrc文件
        "flow"
    ]
}

2. 配置package.json添加build命令调用babel··· json {
    "scripts": {​
        "build": "babel ./src -d ./dist"
    }
}
3. 执行build命令对文件进行转换
npm run build


// 四,作用
// 使用flow可以简化代码
/**
 * 
 * @param {*} arr 传递一个数组进来,数组中包含数字
 * 函数计算出数组中所有数字的和,进行返回
 */
// function sum(arr) {
//     // 检查函数调用时是否有参数传入
//     if (!arr) {
//         throw new Error("此函数需要传递一个数组作为参数");
//     }
//     // 检查函数调用时传出的参数是否为数组
//     if (!Array.isArray(arr)) {
//         throw new Error("此函数需要传递一个数组作为参数");
//     }
//     // 检查用户传递进来的参数数组,是否为数字数组
//     if (!arr.every(v => typeof v == "number")) {
//         throw new Error("此函数需要传递一个数组作为参数, 数组中的元素需要全部为数字");
//     }
//     let result = 0;
//     arr.forEach(v => {
//         result += v;
//     })
//     return result;
// }

function sum(arr: Array < number > ) {
    let result = 0;
    arr.forEach(v => {
        result += v;
    })
    return result;
}

// sum([1, 2, 3]);
// sum();
// sum('abc');
sum(['a', 1, 2]);


// 五:介绍
#
JavaScript语言特征介绍( 类型)
JavaScript是一种弱类型的, 动态类型检查的语言。

## 弱类型和强类型

### 弱类型?
在定义变量的时候, 我们可以为变量赋值任何数据, 变量的数据类型不是固定死的, 这样的类型叫做弱类型
    ``
`js
var a = 10;
a = "abc";
a = [];
a = function(){};
`
``###
强类型?
在声明变量的时候, 一旦给变量赋值, 那么变量的数据类型就已经确定, 之后如果要给该变量赋值其他类型的数据, 需要进行强制数据类型转换。
    ``
`java
int a = 10;
a = "10";
`
``##
动态类型和静态类型
动态类型和静态类型的核心区别: 动态类型的类型检查会在代码运行的时候进行, 而静态类型的类型检查则是在编译时进行。

运行时类型检查
    ``
`js
var obj = {};
obj.forEach(function(v, i){})
`
``

编译时类型检查
    ``
`java
int num = 100;
num = "abc";
`
``

// 六,动态类型问题,静态类型好处
问题:
    // 动态类型,类型检查的操作是在运行时进行的。
    // 代码中的错误,只能在代码运行的时候被发现

    // var num = 123;
    // var num1 = 456;

    // /**
    //  * 函数接收两个参数,两个参数需要是数值类型的
    //  * 函数的返回值为两个参数的和
    //  */
    // function sum(a, b) {
    //     return a + b;
    // }

    // // console.log(sum(num, num1));

    // console.log(sum("abc", 1));

    function greet(obj) {
        obj.sayHello();
    }
var o = {
    name: "张学友"
};
greet(o);

好处: #静态类型的优势

## 提早发现代码中的Bug

##
提高代码的可读性
// 如果能指定a和b的类型
// 指定为数字,这个函数的功能就非常明确了
// a: number
// b: number
// 返回值: number
function sum(a, b) {
    return a + b;
}

##
减少了复杂的错误处理逻辑

这个函数接收一个数字数组作为参数
返回这个数组中所有数字的和

// function sum(arr){
//     let result = 0;
//     arr.forEach(v => {
//         result += v;
//     })
//     return result;
// }

function sum(arr) {
    // 首先判断用户是否有传递参数进来
    if (!arr) {
        throw new Error("函数需要传参");
    }
    if (!Array.isArray(arr)) {
        throw new Error("函数需要一个数组作为参数");
    }
    if (!arr.every(v => typof v == 'number')) {
        throw new Error("函数需要的数组为数字数组!")
    }

    let result = 0;
    arr.forEach(v => {
        result += v;
    })
    return result;
}
sum([1, 2, 3]);
sum(['a', 'b'])
sum()

##
便于代码重构

function test(num) {
    console.log(num)
}
test({ name: "郭富城" })

##
增强IDE的功能
IDE: 集成开发环境
原文地址:https://www.cnblogs.com/xm0328/p/13832800.html