TypeScript-如何定义函数类型

前言

函数是JavaScript中的一等公民,任何程序都需要使用函数构建抽象,TypeScript为了增强JavaScript中函数的能力,增加了别的强类型语言函数的用法。

一、基本使用

function add(x: number, y: number): number {
  return x + y;
}

这里对参数和函数的返回值进行类型定义,要求xy必须是numer类型,返回值必须是number类型。

函数的返回类型,TypeScript类型检查系统会根据函数体的返回值自行进行判断,所以你也可以这样做:

function add(x: number, y: number){
  return x + y;
}

这在TypeScript中也是合理的。

也可以使用箭头函数定义匿名函数

let secondAdd: (x: number, y: number) => number;
secondAdd = function(x: number,y: number) {
  return x + y;
}

同时和之前的例子一样,当你在函数引用中定义好了函数的参数类型和返回值类型,那么函数体不需要再次指定类型:

secondAdd = function(x,y) {
  return x + y;
}

二、可选参数

在JavaScript中函数的参数个数一旦定义,调用函数的时候就必须传入相同个数的参数。

比如:

function xAddy(x, y) {
  return x + y;
}

然后调用的时候我们只传入一个参数:

xAddy(1) 
// Expected 2 arguments, but got 1

TypeScript中我们可以使用可选参数,使得函数的定义更加灵活:

function times(x: number, y?: number) {
  if (y) {
    return x * y
  }
  return x;
}

console.log(times(2));
// 2
console.log(times(2,3));
// 6

三、默认参数值

TypeScript中允许给指定参数值的函数参数指定默认值:

function secondTtimes(x: number, y = 3) {
  return x * y;
}

console.log(times(2));
// 6

四、剩余参数

JavaScript中ES6也提出了剩余参数的概念,TypeScript中只是在此基础上了加了类型校验。

function thirdTimes(x: number, ...restOfNum: number[]) {
  let result = x;

  for (let i = 0; i < restOfNum.length;i++) {
    result += restOfNum[i];
  }

  return result;
}

console.log(thirdTimes(2));
// 2
console.log(thirdTimes(2,3,5));
//10

五、函数中的this

使用函数,必定会涉及到this的指向问题,我们知道在JavaScript中this指向是一个让人很令人头疼的事情,TypeScript为this的使用加了新特性:允许你指定this的指向,并且可以将指定后的this作为函数的参数,this一旦指定后,其指向不会再改变。

定义一个简单的接口

interface thisObj {
  name: string
  getName:() => () => string
}

然后这样来使用这个接口:

let obj: thisObj = {
  name: '马松松',
  getName: function(this: thisObj) {
    return () => {      
      return this.name;
    }
  }
}
let nameFunc = obj.getName();
console.log(nameFunc())
// 马松松

注意这里我们将this指定为了thisObj对象,在之前的JavaScript中,这样调用这个函数,this的指向是在非严格模式下是全局对象。

不过我这里有个疑问,既然this可以作为参数传递,那我这样使用可以吗?

let obj: thisObj = {
  name: '马松松',
  getName: function(this: thisObj) {
    return function(this:thisObj) => {      
      return this.name;
    }
  }
}
let nameFunc = obj.getName();
console.log(nameFunc())

在这里我没有使用箭头函数,直接使用匿名函数,但是经过我的测试,这样使用竟然是不行的。

六、重载

TypeScript中也允许使用重载,所谓的重载是,定义多个函数名相同、传入参数类型不同的函数,根据不同的参数类型,由编译器选择执行匹配的函数。

首先定义重载列表,TypeScript会对重名的函数进行类型的匹配:

function overLoadE(x: {name: string,age: number}): string | number;
function overLoadE(x: string | number): {name?: string,age?: number};
function overLoadE(x: any):any{
  if (typeof x == 'object') {
    return `你的名字是:${x.name},你的年龄是${x.age}`;
  }

  if (typeof x == "string") {
    return {name: x}
  }

  if (typeof x == 'number') {
    return {age: x}
  }
}

然后传入不同的参数:

console.log(overLoadE({name: '马松松', age: 18}));
// 的名字是:马松松,你的年龄是18
console.log(overLoadE("马松松"));
// { name: '马松松' }
console.log(overLoadE(18));
// { age: 18 }

你可能感兴趣的:(TypeScript-如何定义函数类型)