TypeScript前奏

文章说明:本文章为拉钩大前端训练营所做笔记和心得,若有不当之处,还望各位指出与教导,谢谢 !

TypeScript可大大提高代码的可靠程度。该系列文章主要介绍:

  • 强类型与弱类型
  • 静态类型与动态类型
  • JavaScript自有类型系统问题
  • Flow静态类型检查方案
  • TypeScript语言规范与基本应用

一、类型系统:强类型与弱类型

  • 强类型与弱类型(类型安全的角度) :语言层面限制函数的实参类型必须与形参类型相同

class Main{
    static void foo(int num){// 强类型,接收一个整型的参数,调用时就不允许传入其它类型的值
        System.out.println(num);
    }

    public static void main(String[] args){
        Main.foo(100);// ok
        Main.foo('100');// error "100" is a string
        Main.foo(Integer.parseInt("100"))//ok  传入前转化成整型的数字
    }
}
//弱类型,弱类型语言层面不会限制实参的类型
function foo(num){// 调用时任然可以传入任意类型数据,语法上是不会报错的,运行上可能出问题
    console.log(num)
}

foo(100) //ok
foo('100')//ok
foo(parseInt('100'))//ok

由于这种强弱类型之分根本不是某一个权威机构的定义,强类型有更强的类型约束,而弱类型中几乎没有什么约束,强类型语言中不允许任意的隐式类型转换,而若类型语言则允许任意的数据隐式类型转换,比如我们这需要的是一个数字,而你放了个字符串也是可以的。变量类型允许随时改变的特点,不是强弱类型的差异。python 是一门强类型的语言,但是变量任然是可以随时改变类型的

二、静态类型与动态类型

  • 静态类型:一个变量声明时它的类型就是明确的,声明过后,它的类型就不允许再修改

  • 动态类型:运行阶段才能够明确变量类型,而且变量的类型随时可以改变

  • 运行过程中被赋予字符串,也是允许的,动态类型语言中的变量没有类型,变量中存放的值室友类型的,JavaScript就是一门标准的动态类型语言

var foo = 100

foo = 'bar' //ok 运行过程中被赋予字符串,也是允许的,动态类型语言中的变量没有类型,
//变量中存放的值室友类型的,JavaScript就是一门标准的动态类型语言

console.log(foo)
  • 弱类型就是动态类型,强类型就是静态类型,这种说法是不正确的

 JavaScript 类型系统特征 :弱类型 且 动态类型 (类型) 缺失了类型系统的可靠性(不靠谱),早前的javascript应用简单,类型的限制会比较多余麻烦,JavaScript没有编译环节,设成静态语言没有意义(静态语言在编译时要做检查)

三、弱类型的问题

JavaScript 弱类型产生的问题

  • 因为弱类型的关系,程序当中的类型异常需要等到运行时才能够发现

const obj ={}

obj.foo()//obj.foo is not a function  运行时才报错

setTimeout(() =>{
    obj.foo()//在刚刚启动运行时还没发现异常,等到这行代码执行了才抛出这个异常,如果测试过程中没测到,这个就是个隐患,若是强类型,则直接报错。
},1000000)
  • 因为弱类型的关系,类型不明确就造成函数功能可能会发生改变

function sum(a,b){
    return a+b
}

console.log(sum(100,100)) //200
console.log(sum(100,'100'))//100100 直接拼接了,若是强类型,语法上行不通
  • 因为弱类型的关系,引起我们对对象索引器错误的用法

const obj = {}

obj[true] = 100

console.log(obj['true']) // 100 如果说我们不知道对象属性名会自动转换成字符串的特点,那这里可能就会感觉很奇怪,这种奇怪的根源就是我们用的是比较随意的弱类型语言,强类型则直接报错

君子约定有隐患,强制要求有保障

四、强类型的优势

  • 错误更早暴露,编码阶段就能暴露出来

  • 代码更智能,编码更准确

  • 重构更牢靠

  • 减少不必要的类型判断

五、FLOW 快速上手 

Flow:javaScript的类型检查器,相比TypeScript只是一个小工具,Flow是以npm 的一个模块去工作的。Flow 是 Facebook 出品的一个用于 JavaScript 代码的静态类型检查工具。用于找出 JavaScript 代码中的类型错误。

function sum(a:number,b:number){//x,y的类型时number,返回的值的类型时number
    return a+ b
}

sum(100,100)

sum('100','100')

安装过程可以使用yarn和npm安装,推荐使用yarn,因为安装起来会更快。

  • 初始化模块

yarn init -yes

  • 安装flow
  • yarn add flow-bin -dev
  • 使用flow类注解

1.必须在文件开始出标记:@flow

2.关闭vscode语法校验:搜索JavaScript validate,找到enable,取消勾选

// @flow

function sum(a:number, b:number) {
	return a + b;
}

sum(100, 100)
sum('100', '100')

let num:number = 100
num = '100'

 

开始使用:

yarn flow init
yarn flow  # 第一次会很慢,后续会很快
# yarn flow stop # 结束flow

#Error ---------------------------------------------------------------------------------------------------- 01/01.js:8:12

#Cannot call `sum` with `'100'` bound to `b` because string [1] is incompatible with number [2]. [incompatible-call]

#   01/01.js:8:12
#   8| sum('100', '100')
#                 ^^^^^ [1]

#References:
#   01/01.js:3:26
#   3| function sum(a:number, b:number) {
#                               ^^^^^^ [2]

六、Flow 编译移除注解

  • 方案一:自动移除类型注解,官方提供的模块:
yarn add flow-remove-types --dev
yarn flow-remove-types . -d dist //第一个命令:.  为文件所在位置(当前目录)  -d 指定转换后的输出目录,我们放在dist文件下
  • 方案二:babel
yarn add @babel/core @babel/cli @babel/preset-flow --dev

然后再项目中添加项目文件 .babelrc,然后再文件中输入:

{
    "presets":["@babel/preset-flow"]
}

随后使用命令行

yarn babel src -d dist

七、Flow 开发工具组件

更加直观体现当前代码当中的问题。VS Code搜索插件 flow language support, flow官方提供的插件,可以实时显示类型异常。默认情况下,修改完代码,需要重新保存后才会检测类型异常。

flow官网:https://flow.org/en/docs/editors

八、类型推断

flow支持在代码编写过程中就进行类型推断,例如下面代码中,需要算一个数的平方,当传入非数字类型时,flow会进行代码提示,抛出类型错误

// @flow

function square(n: number) {
	return n * n;
}

square('100')

九、类型注解

在绝大多数情况下,flow可以帮我们推断出来变量或者是参数的具体类型,所以说从这个角度上来讲没有必要给所有的成员添加类型注解,但是添加类型注解它可以更明确的限制类型而且后期理解这里的代码也是更有帮助的,所以我们还是尽可能使用类型注解,类型注解还可以用来标记变量的类型和函数返回值的类型

let num:number = 100;
// num = 'string',此时只能赋值数字类型

function foo():number {
    return 100
}
// 此时函数只能返回数字类型,如果函数没有返回值,默认返回undefined,那么也会提醒报错。没有返回值的函数,我们需要将函数返回值类型标注为void
function foo():void {
}

十、原始类型

在flow当中使用的类型有很多,最简单的就是JavaScript当中的原始数据类型,目前原始类型共有6种,number、boolean、string、null、undefined、symbol。

/**
 * 原始类型
 *
 * @flow
 */

const a: string = 'foobar'

const b: number = Infinity // NaN // 100

const c: boolean = false // true

const d: null = null

const e: void = undefined

const f: symbol = Symbol()

十一、数组类型

/*
数组类型
@flow

*/

const arr1:Array<number> = [1,2,3] // 表示全部由数字组成的数组
const arr2:number[] = //同样可以表示全部由数字组成的数组
//元组
const foo:[string,number] = ['foo':100]//只能够存放包含两位元素的数组,第一位是字符串,第二位是数字,对于这种固定长度的数组称为元组,一般这种元祖我们在一个函数当中同时要去返回多个返回值的时候,我们就可以使用这种元组的数据类型

十二、对象类型

/*
    对象类型
    @flow
*/

const obj1:{foo:String,bar:number} ={foo:'string',bar:100}

const obj1:{foo?:String,bar:number} ={bar:100}// 属性后面添加问号表示可有可无的了

const obj3:{[string]:string} = {}//键和值都设为string类型,这种类型限制的意思是表示当前对象允许添加任意类型的键,不过键和值的类型都必须是字符串

obj3.key1 = 'vlaue1'
obj3.key2 = 'value2'

十三、函数类型

/*
    函数类型

    @flow

*/

function foo(callback:(string,number) => void){ // 接收参数类型分别为字符串和数字,该函数的返回值为没有(void)
    callback('string',100)
}

foo(function (str,n){
    // str => string
    // n => number
})

十四、特殊类型

/*
    特殊类型

    @flow

*/

cosnt a:'foo' = 'foo'//字面量类型:用来限制我们的变量必须是某一个值,a变量当中只能够存放这个值'foo'

const type:'success' |'warning'|'danger'='success' //只能存放这三种值之一

//使用type关键词去单独的声明一个类型,用来去表示多个类型联合过后的一个结果

type StringOrNumber = string | number

const b:string | number = 100 //这个值类型只能是字符串或者数字
const b:StringOrNumber = 100 //这个类型的别名可以重复使用了

//maybe类型====================================

const gender:?number = 0 //需要此时变量为空,则在number前面加上?,表示这个变量除了可以接收number以外还可以接收null或者undefined
//相当于下面用法

const gender:number | null | void = undefined  

十五、Mixed与any

/*
Mixed Any

@flow

*/

function passMixed(value:mixed){//mixed 类型实际上是所有类型的联合类型,可以理解成//string 或者 number 或者Boolean或者是其它任何一个类型

    value.substr(1)  //mixed是强类型,直接报语法错误,前面要加个类型判断if(typeof value === 'string)

    value*value //mixed是强类型,直接报语法错误if(typeof value === 'number')
}

passMixed('string')

passMixed(100)

//any跟mixed用法类似==========================================

function passAny(value:any){ //any 是弱类型,mixed仍然是强类型
    value.substr(1)  //可以把value当做任意类型使用,例如把它当做一个字符串,调用substr方法

    value*value //也可以当做一个数字,做乘法运算,语法上不会报错,并不是说运行阶段会报错,所以说any是弱类型
}

passAny('string')

passAny(100)

//尽量不要使用any,老代码和新代码可能要做到一个兼容,就用到any类型

十六、flow小结

更多详情见https://www.saltycrane.com/cheat-sheets/flow-type/latest/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值