目录Flow类型推断whereFlow类型注解使用FlowTypeAnnotationstypereferenceURLoriginaltypearraytypetuple-TupleTypesobjecttypegeneralnotationaddoptionalattributesMapclassmixeduseFunctionTypeFunctionParametersOptionalFunctionParametersRestParametersFunctionReturnsSpecialTypeLiteralTypeMaybeTypeMixed和AnyMixedAny的区别FlowRuntimeEnvironmentAPI之前写过Flow的相关介绍。想复习的话可以参考Flow(一)——JavaScriptStatictypechecker,这里简单介绍一下Flow的语法。理解Flow的意思就是可以在第三方源码中看到Flow的用法,可以帮助我们更好的理解源码。Flow类型推断不执行变量类型,但是可以根据代码的用法推断出类型,称为类型推断//@flow//因为字符串不能相乘,所以也会报错functionsquare(n){returnn*n}square('100')但是,虽然有类型推断,但还是建议开发者为可读性添加每个类型。大部分使用Flow类型注解的地方都可以推断出变量类型,但并不代表我们不需要为每个变量都加上类型注解。添加类型注解可以明确的限制类型,对于我们后面理解这里的代码有很大的帮助。建议尽量使用类型注解类型可以标注的地方Functionparametervariablefunctionreturnvalue//@flow//FunctionparameterannotationtypeAnnotationfunctionsquare(n:number){returnn*n}//variableannotationtypeannotationletnum:number=100//函数返回值annotationtypeannotationfunctionfoo():number{return100}//以上情况,如果没有返回值,默认返回undefind,而上面会报错//所以如果没有返回值,需要将返回类型标记为voidfunctionfoo1():void{}FlowTypeAnnotations类型参考URL流官网TypeAnnotationsflow-cheat-sheets3rdPartyTypesManualPrimitiveTypes//@flow//Stringconsta:string='foobar'//Numberconstb1:number=100constb2:number=NaNconstb3:number=Infinity//Infinity//Booleanconstc1:boolean=trueconstc2:boolean=false//nullconstd:null=null//undefinedconste:void=undefined//symbolconstf:symbol=Symbol()arraytype//@flow//方式一:Array后面要加泛型参数,number指定一个所有数字组成的数组,如果有其他类型,会报错constarr1:Array=[1,2,3]constarr2:Array=[1,true,"three",{a:'1',b:2}]//写法二:constarr3:number[]=[1,2,3]除了这种数组写法,还有一种特殊的固定长度的数组,我们称之为-TupleTuple-TupleTypesfixed-length数组,如果改变长度,会报错下标对应的元素必须是指定的类型。设置新值时,也必须匹配元组,不能匹配数组类型,因为数组类型的长度是不确定的,不能在元组上使用改变数组的方法,例如:copyWithin,fill,pop,push,reverse,shift,sort,splice,unshift//@flow//tuple-定长数组//下面的数组指定了两个元素,如果改变了长度,会报错,对应的元素下标必须是指定的类型constarr4:[string,number]=['foo',100]arr4[2]=1//不能将`1`赋值给`arr3[2]`因为元组类型[1]只有2个元素,因此索引2超出范围。constitem0:string=arr4[0]//有效!constitem1:number=arr4[0]//不能将`arr3[0]`赋值给`item1`,因为string[1]与number[2]不兼容对象类型的常用写法决定了哪些key值在一个对象,并且每个对象是什么类型//@flowconstobj1:{foo:string,bar:number}={foo:'string',bar:100}//如果你访问一个不在obj1中的属性,之前会返回undefined,现在直接作为类型错误obj1.baz//Cannotget`obj1.baz`becauseproperty`baz`(didyoumean`bar`?)ismissinginobjecttype[1]Addoptionalproperties可选属性可以未定义或省略,但不能为null//如果foo是可选的,在foo后面加问号//可选属性可以未定义或省略,但不能为nullconstobj2:{foo?:string,bar:数字}={酒吧:100}obj2。foo=未定义//作品!obj2.foo=null//不能将`null`赋给`obj2.foo`因为null[1]与string[2]不兼容Map类key的类型初始化为带方括号的空//可以自己添加key值对,指定键为字符串类型,值也为字符串类型constobj3:{[string]:string}={}obj3.key1='value1'obj3.key2=100//annotassign`100`to`obj3.key2`因为number[1]与string[2]不兼容混合使用Map类和普通的可以混合//@flowvarobj:{size:number,[id:number]:string}={size:0};functionadd(id:number,name:string){obj[id]=name;obj.size++;}函数类型一般是指类型注解函数参数的参数类型和返回值类型//@flow//参数输入决定类型functionsquare(n:number){returnn*n}optionalfunctionparameterfunctionfunc1(num?:number){constn=num?num:1console.log(n)}func1()//1可以接受undefined,不接受nullfunc1(2)//2func1(null)//Error!Restarguments//@flowfunctionmethod(...args:Array){//...}方法();//有效。方法(1);//工作方法(1,2);//工作方法(1,2,3);//Works.functionreturns//返回值决定类型//有返回值函数foo():number{return100}//无返回值functionfoo1():void{}//回调函数参数和返回值类型functionfunc(callback:(string,number)=>void){callback('string',100)}func(function(str,n){//str=>string//n=>number//无返回值})特殊类型字面量类型不同于传统类型。这个字面量类型必须限制变量为某个值,一般不会单独使用,会配合联合类型组合几个特性的值//@flow//下面定义了n个字面量,值只能存储foo字符串,不能替换为其他字符串和其他类型constn:'foo'='foo'//只能是以下三种字符串类型之一(以下是联合类型,也称为or类型)常量类型:“成功”|'警告'|'danger'='success'//b变量可以是字符串或数字,也可以是字符串或数字constb:string|number='string'//100//也可以自己定义一个类型,StringOrNumber是一个类型的别名typeStringOrNumber=string|numberconsttest:StringOrNumber='string'//可能有100种类型,在基本类型的基础上扩展null和undefined类型//@flow//添加?可以使用null和undefinedconstgender:?number=nullconstgender1:?number=undefinedconstgender2:?number=100//等价于下面的numberornullorundefinedconstgender:number|空|void=undefinedMixed和AnyMixedMixed可以接收任何类型的Value,它是所有类型string|的联合类型麻木的呃|布尔|...//参数为mixed类型functionpassMixed(value:mixed){console.log(value)}passMixed('string')//stringpassMixed(100)//100Any和Mixed一样,可以接收任意typeofvaluefunctionpassAny(value:any){console.log(value)}passAny('string')//stringpassAny(100)//100两者的区别Mixed是强类型,如果有隐患ofuse如果报错,只能用typeof来判断类型。Any是弱类型。如果使用中有隐患,不会报语法错误。Mixed是安全的(推荐),Any是不安全的。存在的意义是为了兼容旧代码//Mixed//如果不清楚变量是字符串还是数字,不能直接使用,会报错functionpassMixed(value:mixed){console.log(value)value=value**2//无法进行算术运算,因为mixed[1]不是数字}//如果要解决上面的问题,需要使用typeof进行类型判断函数passMixed(value:mixed){if(typeofvalue==='string'){value.substr(1)}if(typeofvalue==='number'){value**2}}//任意//以下语法不会报错,运行时不确定functionpassAny(value:any){value=value**2}FlowruntimeenvironmentAPIJavaScript需要在一定的环境下运行,例如:浏览器环境或节点环境。它们有自己的API,比如浏览器中的DOM和BOM,node中的path等,我们在flow中也会用到这些对象。那么这些都有特殊的类型限制,例如:document.getElementById()//参数里面传一个字符串,数字会报错//这是浏览器环境内置API的一些限制document.getElementById('app')//返回对应的类型为HTMLElement//如果没有找到对应的元素,也返回null类型,所以接收的时候可以写constelement:HTMLElement|null=document.getElementById('app')右键跳转到定义看里面有一些官网仓库给出的类型声明。开发时可以参考core-JS标准库的成员:object、array、math、JSONdombomcssomnode