从零到一学习TypeScript (三) 函数

508 阅读4分钟

讲函数之前 我们在学习一点知识点

  • 1. 类型缩小

什么是类型缩小呢?

类型缩小的英文 是Type Narrowing, 我们可以通过 typeof 'erke' === 'string' 来改变我们代码执行的路径, 在我们执行代码的过程中 我们可以执行到比我们声明时更小的类型 这个过程称之为 缩小

我们通过 缩小类型 来达到类型保护的效果(type guards)

常见的类型保护有以下几种

  • typeof

  • ===, !==

  • instanceof

  • in

  • Object.prototype.toString.call(add)


  • typeof 的类型缩小

在Typescript中 检查类型的值使得 typeof 是一种类型保护 根据typeof 操作不同的值

type nameType = number | string
function getName(name: nameType): void {
  if (typeof name === 'string') {
    console.log(name.toUpperCase());
  } else {
    console.log(name.toFixed(2));
  }
}
getName('erkelost') // ERKLOST
getName(123456) // 123456.00

  • switch 平等缩小 的类型缩小

type styleType = "padding" | "margin" | "width" | "height"
function getStyle(style: styleType) {
  switch (style) {
    case 'padding':
      console.log(`${style}=100px`);
      break;
    case 'margin':
      console.log(`${style}=100px`);
      break;
    case 'width':
      console.log(`${style}=100px`);
      break;
    case 'height':
      console.log(`${style}=100px`);
      break;

  }
}
getStyle('padding') // padding = 100px
  • instanceof

type mathType = number | Date
function math(num: mathType) {
  if (num instanceof Date) {
    console.log(new Date());
  } else {
    console.log(num);
  }
}
math(new Date())
math(132456)

  • in

in 运算符 确定对象是否具有带名称的属性 in 运算符 如果指定属性在指定的对象 或者原型链中就返回 true

type Fish = {
  swimming: () => void
}

type Dog = {
  running: () => void
}

function walk(animal: Fish | Dog) {
  if ('swimming' in animal) {
    animal.swimming()
  } else {
    animal.running()
  }
}

const fish: Fish = {
  swimming() {
    console.log("swimming")
  }
}
walk(fish) // swimming
export{}

函数

在JavaScript开发中,函数是重要的组成部分,并且函数可以作为一等公民(可以作为参数,也可以作为返回值进行传递)

1. 当函数作为参数时
function name() {
  console.log('adny');
}
type getType = () => void  // 默认定义一个没有返回值的函数类型
function get(fn: getType) {
  fn()
}
get(name)
export{}

2.定义常量时 编写函数的类型 类型返回一个number 就是返回一个number 类型 不写就是void 没有返回值

type constFnType = (n1: number, n2: number) => number
const addNum: constFnType = (a1: number, a2:number) => {
  return a1 + a2
}
console.log(addNum(20, 50));  // 70

3.参数的可选类型(y的可选类型就是number类型和undefined联合类型)

function foo(x: number, y?: number): number {
  console.log(x + y);
  return x + y  
}
foo(20, 30)
foo(20)

4. 默认参数

function adny(y: number, x: number = 10): number {
  console.log(x, y)
  return x + y
}

adny(30)

this

正常情况下 TypeScript认为函数 sayName 有一个对应的this的外部对象 info,所以在使用时,就会把this当做该对象

const info = {
  name: 'adny',
  sayName:function() {
    console.log(this);
    console.log(this.name); // adny
  }
}
info.sayName()

但是如果我们把函数写在外面 那么就会报错 this值是获取不到的, 我们不能确定this到底是什么 对于Typescript来说 代码是不安全的 编译的时候 会报错

function sayName() {
  console.log(this.name);  // An outer value of 'this' is shadowed by this container.
}

const info = {
  name: 'adny',
  sayName
}
info.sayName()

所以我们需要指定this的类型 这里我们再次强调一下,TypeScript进行类型检测的目的是让我们的代码更加的安全

type thisType = {  // 定义一个对象类型
  name: string
}
function sayName(this: thisType) { // 我们定义的this要指定我们能找到这个对象
  console.log(this.name);
}

const info = {
  name: 'adny',
  sayName
}
info.sayName()

函数的重载

在typescript中 如果我们编写了一个 add函数 对可能会有不同类型的变量进行相加,我们可以设置

function addS(num1: number | string, num2: number | string): number | string {
  return num1 + num2
}

这是因为 运算符“+”不能应用于类型“string | number”和“string | number”。

在typescript 中 我们可以编写不同的重载签名(overload signatures)来表示函数可以以不同的方式进调用;一般是编写两个或者以上的重载签名,再去编写一个通用的函数以及实现

函数的重载定义就是 函数的重载: 函数的名称相同, 但是参数不同的几个函数, 就是函数的重载

在我们传递参数 调用函数的时候 会根据我们传入的参数 来决定我们到底要调用那些执行函数

function addS(num1: number, num2:number): number
function addS(num1: string, num2:string): string
function addS(num1: any, num2: any): any {
  console.log(num1 + num2);
  return num1 + num2
}

addS('ERKELOST','adny') // ERKELOSTadny
addS(20, 30) // 50

联合类型 和 重载

定义一个函数 我们需要传入字符串 和 数组 获取数组 或者 字符串的长度

我们可以使用联合类型

type lengthType = string | any[]
function getLength(len: lengthType): number {
  console.log(len.length);
  return len.length
}
getLength([1,2,3]) // 3
getLength('hhjjk') // 5

重载

function getlength(len: string) :number
function getlength(len: any[]) :number
function getlength(len: any) {
  return len.length
}