函数详解
函数的标注
一个函数的标注包括函数参数的标注以及函数返回值的标注
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') {} // ok
sort([1,2,3]);
sort([1,2,3], 'asc');// ok
sort([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:number
fn:(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") //这里没在函数重载里面定义相关的逻辑,就会检查出问题
}