函数详解
函数的标注
一个函数的标注包括函数参数的标注以及函数返回值的标注
function fn(a:string):string{};// 直接标注let fn:(a:string)=>string=function(a){} //声明式标注type callback=(a:string):string; //类型别名方式标注interface ICallBack{ //接口方式标注(a:string):string;}let fn:callback=function(a){};let fn:ICallBack=function(a){};
可选参数和默认参数
可选参数
通过函数名后面添加?来标注该参数是可选的
let div = document.querySelector('div');function css(el: HTMLElement, attr: string, val?: any) {}div && css( div, 'width', '100px' ); // 设置div && css( div, 'width' ); // 获取
默认参数
我们还可以给参数设置默认值
- 有默认值的参数是可选的
- 设置了默认值的参数是可以根据值自动推导类型
function sort(items: Array<number>, order = 'desc') {}sort([1,2,3]);// 也可以通过联合类型来限制取值function sort(items: Array<number>, order:'desc'|'asc' = 'desc') {} // oksort([1,2,3]);sort([1,2,3], 'asc');// oksort([1,2,3], 'abc');// error
剩余参数
剩余参数是一个数组所以标注的时候一定要小心
interface Iobj{[key:string]:any}function merge(target:Iobj,...others:Array<Iobj>){return others.reduce((prev,current){prev=Object.assign(prev,current);return prev},target)}let newObj = merge({x: 1}, {y: 2}, {z: 3});
函数中的this
无论是javascript还是typescript,函数中的this都是我们需要关心的,那函数中的this的类型该如何标注呢
普通函数
对于普通函数而言,this是会随着调用环境的变化而变化的,所以默认情况下,普通函数中的this被标注为any,但我们可以在函数的第一个参数位(它不占据世纪参数位置)上显示的标注this的类型
interface T {a:numberfn:(x:number)=>void;}let obj:T ={a:1,fn(x:number){console.log(this)}}let obj2 :T={a:1,fn(this:T,x:number){//通过第一个参数位标注 this 的类型,它对实际参数不会有影响console.log(this)}}obj2.fn(1);
箭头函数
箭头函数的this不能像普通函数那样进行标注,他的this标注取决于它所在的作用域this的标注类型
interface T {a:number ;fn:(x:number)=>void;}let obj2:T={a:2,fn(this:T){return ()=>{console.log(this)}
函数重载
有的时候,同一个函数会接收不同类型的返回值,我们可以使用函数重载来实现
function showOrHide(ele:HTMLElement,attr:string,value:"block"|"none"|number){//}let div=document.queryselector("div");if(div){showOrHide(div,"display","none");//这样是符合标准的showOrHide(div,"opacticy",1); //这样也行//但是会出现这么一种情况就是showOrHide(div,"display",1) //这样也是可以的但是这样明显是错误的// error,这里是有问题的,虽然通过联合类型能够处理同时接收不同类型的参数,但是多个参数之 间是一种组合的模式,我们需要的应该是一种对应的关系}
函数重载写法
function showOrHide(ele:HTMLElement,attr:'display',value:'block'|'none);function showOrHide(ele:HTMLElement,attr:'opacity',value:number);function showOrHide(ele:HTMLElement,attr:string,value:any){ele.style[attr]=value}let div=document.querySelector('div');if(div){showOrHide(div,'display','none');showOrHide(div,'opacity',1);showOrHide(div,'display',1);//这个时候类型系统就会检查到错误并且提醒用户}
重载函数类型只需要定义结构,不需要实体,类似接口
interface PlainObject{[key:string]:string |number}function css(ele:HTMLElement,attr:PlainObject);function css(ele:HTMLElement,attr:string,value:string|number);function css(ele:HTMLElement,attr:any,value?:any){if(typeof attr==='string' && value){ele.style[attr]=value;}if (typeof attr==='object'){for (let key in attr){ele.style[attr]=attr[key]}}}let div =document.queryselector('div');if(div){css(div,'width','100px');css(div,{width:"100px"});css(div,"width") //这里没在函数重载里面定义相关的逻辑,就会检查出问题}
