TypeScript入门之函数

简介: 在 JavaScript中,函数是构建应用的一块基石,我们可以使用函数抽离可复用的逻辑、抽象模型、封装过程。在TypeScript中,函数仍然是最基本、最重要的概念之一。下面就来看看TypeScript中的函数都有哪些特性。

函数定义

直接定义

直接定义这种方式是最好理解的。

function fun_1(num1: number, num2: number): number {
  return num1 + num2;
}

const fun_2 = (num1: number, str1: string): string => {
  return num1 + str1;
};

function fun_3(): void {
  console.log("fun_3");
}

通过表达式定义

const fun_4: (num1: number, str1: string) => string = (num1: number, str1: string) => {
  return num1 + str1;
};

通过类型别名定义

我们还可以把函数表达式定义成类型别名。

type fun5Type = (num1: number, str1: string) => string

const fun_5: fun5Type = (num1: number, str1: string) => {
  return num1 + str1;
};

函数参数

函数参数这块在JS中都有与之对应的特性,基本上差不多。

可选参数

type Add = (x: number, y: number, z?: number) => number;

let add: Add = (arg1, arg2, arg3) => arg1 + arg2 + arg3;

add(1, 2); // success   3
add(1, 2, 3); // success   6

JavaScript中,上面代码中后面两个函数调用都不会报错, 只不过add(1, 2, 3)可以返回正确结果3add(1)会返回NaN。而在TypeScript中我们设置了指定的参数,那么在使用该类型时,传入的参数必须与定义的参数类型和数量一致。

但有时候,函数有些参数不是必须的,我们就可以将函数的参数设置为可选参数。可选参数只需在参数名后跟随一个?即可,这就是可选参数。

需要注意,可选参数必须放在必选参数后面,这和在 JS 中定义函数是一致的。来看例子:

type Add2 = (x?: number, y: number) => number;  // error 必选参数不能位于可选参

// 需要改成
type Add2 = (y: number, x?: number) => number;

默认参数

当为参数指定了默认参数时,TypeScript 会识别默认参数的类型;当调用函数时,如果给这个带默认值的参数传了别的类型的参数则会报错:

const add = (x: number, y = 2) => {
  return x + y;
};
add(1, "ts"); // error 类型"string"的参数不能赋给类型"number"的参数

当然也可以显式地给默认参数 y 设置类型:

const add = (x: number, y: number = 2) => {
  return x + y;
};

默认参数不比可选参数,默认参数可以放在参数列表的任意位置。

const add = (x: number = 2, y: number) => {
  return x + y;
};

当默认参数不在参数列表的第一个的时候我们该怎么使用呢?

// 使用undefined占位就可以啦
add(undefined, 10) // 12

剩余参数

剩余参数与JavaScript中的语法类似,需要用 ... 来表示剩余参数。

const add = (a: number, ...rest: number[]) => rest.reduce(((a, b) => a + b), a)

上面的例子参数 rest 则是一个由number组成的数组,在本函数中用 reduce 进行了累加求和。

函数重载

学过java的通过肯定知道函数的重载和重写。

那么在 TypeScript 中函数重载是怎么定义的呢?

其实跟java也是类似的,就是相同的方法名,只是方法参数列表不一样。和java的区别就是 TypeScript 只能是最后有一个方法来完整实现,而不是每个方法都有对应的实现。

interface Direction {
  top: number;
  bottom?: number;
  left?: number;
  right?: number;
}

// 参数列表可能的情况 1个参数 2个参数 4个参数,只需定义,不需要实现
function assigned(all: number): Direction;
function assigned(topAndBottom: number, leftAndRight: number): Direction;
function assigned(
  top: number,
  right: number,
  bottom: number,
  left: number
): Direction;

// 方法完整的实现
function assigned(a: number, b?: number, c?: number, d?: number) {
  if (b === undefined && c === undefined && d === undefined) {
    b = c = d = a;
  } else if (c === undefined && d === undefined) {
    c = a;
    d = b;
  }
  return {
    top: a,
    right: b,
    bottom: c,
    left: d,
  };
}

assigned(1);
assigned(1, 2);
assigned(1, 2, 3); // 没有定义三个参数的函数,编译阶段直接报错
assigned(1, 2, 3, 4);

最后我们分别传入不同数量的参数,发现只有在三个参数的情况下报错了。因为我们没有定义三个参数的方法。

image.png

相较于JS,函数重载可以让我们在编写代码阶段就能及时发现错误。很大的提升了我们的开发效率。

is关键字

is关键字一般和函数搭配使用。

我们来看个例子

function isString(test: any): boolean {
  return typeof test === 'string';
}

function example(foo: number | string){
  if(isString(foo)){
    console.log(foo.length); // string function
  }
}

example('hello world');

我们看到由于foo: number | stringstringnumber的联合类型,后面又直接使用了.length属性,所以会报错。

image.png

那有什么办法可以解决呢?

第一种我们可以使用类型守卫来解决。比如说使用typeof。如果对类型守卫不了解的可以看看TypeScript学习之类型推断、类型断言、双重断言、非空断言、确定赋值断言、类型守卫、类型别名

function example(foo: number | string) {
  if (isString(foo) && typeof foo === "string") {
    console.log(foo.length); // string类型才有length属性
  }
}

第二种就是使用我们的is关键字。

function isString(test: any): test is string {
  return typeof test === 'string';
}

function example(foo: number | string){
  if(isString(foo)){
    console.log(foo.length); // string function
  }
}

example('hello world');

我们在isString方法后面不再返回boolean类型而是test is string。这句话什么意思呢?

意思就是如果isString方法返回true,就表示参数teststring类型的。所以后面直接调用.length属性就不会报错。

系列文章

TypeScript入门之环境搭建

TypeScript入门之数据类型

TypeScript入门之函数

TypeScript入门之接口

TypeScript入门之类

TypeScript入门之类型推断、类型断言、双重断言、非空断言、确定赋值断言、类型守卫、类型别名

TypeScript入门之泛型

TypeScript入门之装饰器

TypeScript入门之模块与命名空间

TypeScript入门之申明文件

TypeScript入门之常用内置工具类型

TypeScript入门之配置文件

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

相关文章
|
8月前
|
JavaScript 编译器
TypeScript中泛型在函数和类中的应用
【4月更文挑战第23天】TypeScript的泛型在函数和类中提供了灵活性,允许处理多种数据类型。了解泛型是掌握TypeScript类型系统的关键。
|
4月前
|
JavaScript
typeScript基础(3)_ts函数默认值和可选参数
本文介绍了在TypeScript中如何使用函数的默认值和可选参数。展示了如何为函数参数指定默认值,使得在调用函数时可以省略某些参数,以及如何定义可选参数。
236 2
|
3月前
|
移动开发 JavaScript 前端开发
TypeScript:数组类型&函数使用&内置对象
本文介绍了 TypeScript 中的数组类型、对象数组、二维数组、函数、函数重载、内置对象等概念,并通过代码示例详细展示了它们的使用方法。还提供了一个使用 HTML5 Canvas 实现的下雨效果的小案例。
|
3月前
|
JavaScript 前端开发 编译器
【小白入门】 浏览器如何识别Typescript?
【10月更文挑战第1天】浏览器如何识别Typescript?
|
4月前
|
JavaScript 前端开发 编译器
TypeScript,从0到入门带你进入类型的世界
该文章提供了TypeScript的入门指南,从安装配置到基础语法,再到高级特性如泛型、接口等的使用,帮助初学者快速掌握TypeScript的基本用法。
|
4月前
|
JavaScript
typeScript基础(7)_函数的类型
本文介绍了TypeScript中函数的类型,包括函数声明与函数表达式的类型注解,如何定义函数的参数类型、返回类型,以及可选参数和参数默认值。还探讨了函数的剩余参数、如何使用接口定义函数的形状,以及函数重载的概念和实践。
37 0
|
6月前
|
JavaScript 前端开发 程序员
Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等
Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等
95 0
|
6月前
|
JavaScript
TypeScript(六)函数
TypeScript(六)函数
37 0
|
7月前
|
JavaScript 前端开发 程序员
typescript入门笔记分享
typescript入门笔记分享
36 0
|
7月前
|
JavaScript 前端开发 API
TypeScript 函数
TypeScript 函数