TS系列教程八:function

160 阅读4分钟

在ts中定义函数的类型有两种写法

第一种 函数声明

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

参数a和b后边的number分别对应变量的类型,:number代表函数返回值类型,返回值类型不写ts一般都能推断出来的,还是建议都写上,可读性高

第二种 函数表达式

const a=function(a:number,b:number):number{
    return a+b;
}
const d=(a:number,b:number):number=>{
    return a+b;
}
const c:(a:number,b:number)=>number=function(a,b){
    return a+b;
}

上边的写法大同小异,通常都是直接使用箭头函数,毕竟少打那么多字母呢

类型别名

type Add=(a:number,b:number)=>number
const a:Add=(a,b)=>a+b;
const b:Add=(a,b)=>a+b;

如果一个函数类型被多个地方使用,为了简化操作,我们一般定义类型别名。
至于用let 定义函数还有一些知识,个人感觉没啥学习的必要,不会出现这种场景。学了没用不如不学。

Function

ts中还提供了Function这个类型,可以表示任意函数,参数个数任意,参数类型any,某些特殊情况可以使用

const handle=(fn:Funtion)=>fn(1,2);

箭头函数的注意事项

type Person={name:string};
const person=['tom','jack'].map((name):Person=>({name}))

上边用到的es6知识:箭头函数,一条语句可以不写return,对象的参数值和名相同可以省略
下边是匿名函数的写法,可以对比下

type Person={name:string};
const person=['tom','jack'].map(function(name):Person{return {name}})

person的类型其实是Person[]

可选参数

const handle:(a?:number)=>void=(a)=>{}

语法就是:变量名?:类型,上边的变量a,它的类型其实是number|undefined,类似下边

const handle:(a:number|undefined)=>void=(a)=>{}

但是这样写调用的时候如果不传参数会报错的,表示至少传递一个参数

默认值 和js一样

const handle:(a?:number)=>void=(a=5)=>{}
const a=(a=5)=>{}

ts函数定义如果不是别名,还是推荐在等号右边定义类型,上边的第二种写法可以不写?,有默认值就默认为是可选参数,如果加上?是会报错的

const a=(a=5)=>{console.log(a)};
a(undefined)

上边说到了可选参数其实有个类型是undefined,所以传递undefined也是不报错的,但是它会触发默认值,a=5

参数解构的写法

//数组的解构
const handle=([a,b,c]:number[])=>{
    return a+b+c;
}
//或者
const handle=([a,b,c]:[number,number,number])=>{
    return a+b+c;
}
//对象的解构
const handle=({a,b,c}:{a:number,b:number,c:number})=>{
    return a+b+c;
}

当然对象的解构太不美观了,一般使用别名的形式

type Obj={
    a:number,
    b:number,
    c:number
}
const handle=({a,b,c}:Obj)=>{
    return a+b+c;
}

rest剩余参数

rest表示剩余所有的参数,可以是数组统一类型,也可以是元组不同类型

function fn(...ids:number[]){}//数组
function fn(...args:[number,string,string?]){}

如果是元组那么要写上变量类型,可以使用可选参数

只读 readonly

function fn(arr:readonly string[]){
    arr[0]='changed'//报错
}

只读属性只能用于数组和元组

void类型

void类型表示没有返回值

function fn():void{}

如果设置了返回值时void,当return返回值就会报错

function fn():void{
    return 'hello';//报错不能把string类型赋值给void类型
}

没有返回值,其实就相当于返回了undefined,所以下边这个写法也是对的

function fn():void{
    return undefined;
}

下边是一种奇怪的现象记录下,以我的智商有点理解不了,或许仅仅是为了适应js而搞的特殊化,比较统一的解释是在这里ts会认为该返回值没有意思,也不能再次利用

type Fn=()=>void;
const fn:Fn=()=>return 'hello';//不报错
fn().length//报错

局部类型

函数内部定义的类型只能函数内部使用

function fn(){
    type Obj={
        name:string
    };
    let obj:Obj={
        name:'Tom'
    }
    console.log('obj',obj);
}
let obj:Obj={
    name:'Tom'//报错
}

函数重载

function fn(n:number):number;
function fn(n:string):string;
function fn(n:number|string):number|string{
    if(typeof n === "number"){
        return n*2;
    }else{
        return n.toUpperCase();
    }
}

写法就是先把他们分别的格式写出来,最后再写一次完整的格式。通常情况下我们都是直接写完整的这个,如果有特殊要求参数类型和返回值类型必须有对应关系