TS的函数,你了解多少?Typescript系列:(二)函数篇

本文详细探讨了Typescript中的函数,包括返回值约束、参数类型、函数类型表达式、类型缩减、函数进阶等。重点讲解了如何处理函数的泛型、重载、参数的可选性和剩余参数。通过实例展示了如何使用控制流分析、类型预言和穷举校验进行类型缩减,以及如何声明和使用函数中的`this`。对于函数的高级特性,如函数签名、泛型约束和函数重载,提供了实用的指导和最佳实践。
摘要由CSDN通过智能技术生成

TS的函数,你了解多少?Typescript系列:(二)函数篇

函数在我们日常代码中占有绝对重要的地位,深入了解TS中函数的使用对我们的学习十分有利。如果你还不了解泛型函数函数签名函数重载,那么阅读本文将让你对TS中的函数有一个更加细致的理解,必能有所收获。

一、返回值

我们在声明一个函数 / 方法时,可以在括号后加上类型注释,以约束其返回值的类型,如果没有明确约束返回值的类型,则将其推论为any类型。除了void和any之外,其它所有的类型都应该有相应类型的返回值。

  • 返回值如果不是约束的类型,或者约束了类型却没有return相应的类型,则会报错:
// 声明变量时由初始值'cc'进行类型推论,得出_name为string类型
let _name = 'cc'

// 会报错,约束了返回值的类型,却没有return相应的类型,
function getName1():string {
   

}

// 约束了返回值类型只能时string
function getName1():string {
   
  return _name
}

// 定义一个number类型的变量_name2
let _name2 = 18
// 约束函数返回值类型为string
function getName2():string {
   
  // 会报错,返回值应该是string类型,而_name2是number类型
  return _name2
}
  • 当我们实际的返回值有可能不是约束的类型时,也是不正确的:
let _name3: string | number = 'cc'
function getName3():string {
   
  // 不合法的返回值,因为_name3有可能是number类型,而返回值只能是string类型
  return _name3
}
  • 这种情况尤其容易发生在字面量类型上
// _name4经类型推论判定为string类型
let _name4 = 'cc'
// 约束返回值只能为 'cc' | 'yy' 类型
function getName4():'cc' | 'yy' {
   
  // 会报错,虽然_name4的值为'cc',但它是string类型,不符合要求
  // return _name4

  // 可以用类型断言来解决,后面我们将介绍类型来解决
  return _name4 as 'cc'
}
  • 函数的返回值为空时,使用void类型,此时可以return undefined,return null,也可以不写return,会默认返回undefined:
let _name = 'cc'

// 返回空值undefined
function setName(name):void {
   
  _name = name
}

let a = setName('yy')  // a为undefined

二、参数

在TS中我们往往需要对函数的参数添加类型注释,如果不添加类型注释,则该参数将被类型推论为any。TS不仅约束了传参时实参的类型,也约束了在函数内部形参的类型。

let _name = 'cc'
// 定义一个接收string类型,无返回值的函数
function setName2(name: string): void {
   
  _name = name
}

有时候,我们的参数比较复杂,例如多种类型的组合:string | number,这时候我们需要进行类型缩减,以防在return或参数调用方法等情况下出现问题。

let _name = 'cc'

// 错误示例
function setName3(name: string | number): void {
   
  // 参数name有可能是number,因此不能直接赋值  
  _name = name
}

// 正确示例
function setName3(name: string | number): void {
   
  // name是string类型
  if(typeof name === 'string'){
   
    _name = name
  }else{
   
    // name是number类型,可强制转化
    _name = String(name)
  }
}

有时候,某个参数不是必须传的,就可以在形参后加上英文问号"?"来表示可选参数,如果调用函数时不传该参数,则该参数为undefined。因此,在函数体内部,该参数有可能是undefined,也需要进行类型缩减。

let userInfo: {
   name:string, age:number, gender: 1 | 2 | 3};
function setUserInfo(name:string, age:number, gender?: 1 | 2 | 3){
   
  if(gender === undefined){
   
    userInfo.gender = 3
  }else{
   
    userInfo.gender = gender
  }
}

三、函数类型表达式

TS中可以使用箭头函数的形式来定义一个函数类型:(a: Type1, b: Type2, …) => TypeN表示接收的参数名称为a, b , …,类型分别为Type1, Type2,…,返回值类型为TypeN的函数。

// 定义了类型Fn1是一个函数,接收一个string类型的name和number类型的age为参数,
// 返回一个sttring类型的值
type Fn1 = (name: string, age: number)=>string

// 给fn1添加Fn1类型,则参数和返回值都需要满足Fn1的约束
// 已经由Fn1约束了类型,因此无需再对参数和返回值进行类型注释
const fn1: Fn1 = function(name, age){
   
  return 'I am' + name
}

// 也可以使用箭头函数
const fn11: Fn1 = (name, age) => 'I am' + name

在声明对象的方法时,可以很方便地使用函数类型表达式:

// 定义一个User接口,其中包含interest方法,需要传入一个string类型的参数,
interface User {
   
  name: string,
  age: number,
  interest: (something: string)=>void
}

const user: User = {
   
  name:</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值