typescript返回值类型和参数类型的具体使用

 更新时间:2022年06月22日 11:00:06   作者:恪愚  
本文主要介绍了typescript返回值类型和参数类型的具体使用文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

返回值类型

在 JavaScript 中,我们知道一个函数可以没有显式 return,此时函数的返回值应该是 undefined:

function fn() {
  // TODO
}
console.log(fn()); // => undefined

需要注意的是,在 TypeScript 中,如果我们显式声明函数的返回值类型为 undfined,将会得到如下所示的错误提醒。

function fn(): undefined { // ts(2355) A function whose declared type is neither 'void' nor 'any' must return a value
  // TODO
}

此时,正确的做法是使用 void 类型来表示函数没有返回值的类型(这是“废柴” void 类型唯一有用的场景),示例如下:

function fn1(): void {
}
fn1().doSomething(); // ts(2339) Property 'doSomething' does not exist on type 'void'

我们可以使用类似定义箭头函数的语法来表示函数类型的参数和返回值类型,此时=> 类型仅仅用来定义一个函数类型而不用实现这个函数。

需要注意的是,这里的=>与 ES6 中箭头函数的=>有所不同。TypeScript 函数类型中的=>用来表示函数的定义,其左侧是函数的参数类型,右侧是函数的返回值类型;而 ES6 中的=>是函数的实现。

在对象(即接口类型)中,除了使用这种声明语法,我们还可以使用类似对象属性的简写语法来声明函数类型的属性,如:

interface Entity {
    add: (a: number, b: number) => number;
    del(a: number, b: number): number;
}
const entity: Entity = {
    add: (a, b) => a + b,
    del(a, b) {
      return a - b;
    },
};

在某种意义上来说,这两种形式都是等价的。但是很多时候,我们不必或者不能显式地指明返回值的类型,这就涉及可缺省和可推断的返回值类型的讲解。

可缺省和可推断的返回值类型

幸运的是,函数返回值的类型可以在 TypeScript 中被推断出来,即可缺省。

函数内是一个相对独立的上下文环境,我们可以根据入参对值加工计算,并返回新的值。从类型层面看,我们也可以通过类型推断加工计算入参的类型,并返回新的类型,示例如下:

function computeTypes(one: string, two: number) {
  const nums = [two];
  const strs = [one]
  return {
    nums,
    strs
  } // 返回 { nums: number[]; strs: string[] } 的类型 
}

请记住:这是一个很重要也很有意思的特性,函数返回值的类型推断结合泛型可以实现特别复杂的类型推断,比如 Redux Model 中 State、Reducer、Effect 类型的关联。

一般情况下,TypeScript 中的函数返回值类型是可以缺省和推断出来的,但是有些特例需要我们显式声明返回值类型,比如 Generator 函数的返回值。

Generator 函数的返回值

ES6 中新增的 Generator 函数在 TypeScript 中也有对应的类型定义。

Generator 函数返回的是一个 Iterator 迭代器对象,我们可以使用 Generator 的同名接口泛型或者 Iterator 的同名接口泛型表示返回值的类型(Generator 类型继承了 Iterator 类型),示例如下:

type AnyType = boolean;
type AnyReturnType = string;
type AnyNextType = number;
function *gen(): Generator<AnyType, AnyReturnType, AnyNextType> {
  const nextValue = yield true; // nextValue 类型是 number,yield 后必须是 boolean 类型
  return `${nextValue}`; // 必须返回 string 类型
}

注意:TypeScript 3.6 之前的版本不支持指定 next、return 的类型,所以在某些有点历史的代码中,我们可能会看到 Generator 和 Iterator 类型不一样的表述。

参数类型

关于 JS 中函数的参数,在es6之后,统共可以分为:可选参数、默认参数、剩余参数 几个特性。

可选参数和默认参数

在实际工作中,我们可能经常碰到函数参数可传可不传的情况,当然 TypeScript 也支持这种函数类型表达,如下代码所示:

function log(x?: string) {
  return x;
}
log(); // => undefined
log('hello world'); // => hello world

在上述代码中,我们在类型标注的:前添加?表示 log 函数的参数 x 就是可缺省的。

也就是说参数 x 的类型可能是 undefined(第 5 行调用 log 时不传入实参)类型或者是 string 类型(第 6 行调用 log 传入 'hello world' 实参),那是不是意味着可缺省和类型是 undefined 等价呢?

function log(x?: string) {
  console.log(x);
}
function log1(x: string | undefined) {
  console.log(x);
}
log();
log(undefined);
log1(); // ts(2554) Expected 1 arguments, but got 0
log1(undefined);

显而易见:这里的 ?: 表示参数可以缺省、可以不传,但如果传则一定是string类型。也就是说调用函数时,我们可以不显式传入参数。但是,如果我们声明了参数类型为 xxx | undefined,就表示函数参数是不可缺省且类型必须是 xxx 或者 undfined。

因此,在上述代码中,log1 函数如果不显示传入函数的参数,TypeScript 就会报一个 ts(2554) 的错误,即函数需要 1 个参数,但是我们只传入了 0 个参数。

在 ES6 中支持函数默认参数的功能。而 TypeScript 会根据函数的默认参数的类型来推断函数参数的类型,示例如下:

function log(x = 'hello') {
    console.log(x);
}
log(); // => 'hello'
log('hi'); // => 'hi'
log(1); // ts(2345) Argument of type '1' is not assignable to parameter of type 'string | undefined'

在上述示例中,根据函数的默认参数 'hello' ,TypeScript 推断出了 x 的类型为 string | undefined。

当然,对于默认参数,TypeScript 也可以显式声明参数的类型(一般默认参数的类型是参数类型的子集时,我们才需要这么做)。不过,此时的默认参数只起到参数默认值的作用,如下代码所示:

function log1(x: string = 'hello') {
    console.log(x);
}
// ts(2322) Type 'string' is not assignable to type 'number'
function log2(x: number = 'hello') {
    console.log(x);
}
log2();
log2(1);
log2('1'); // ts(2345) Argument of type '"1"' is not assignable to parameter of type 'number | undefined'

上例函数 log2 中,我们显式声明了函数参数 x 的类型为 number,表示函数参数 x 的类型可以不传或者是 number 类型。因此,如果我们将默认值设置为字符串类型,编译器就会抛出一个 ts(2322) 的错误。

同理,如果我们将函数的参数传入了字符串类型,编译器也会抛出一个 ts(2345) 的错误。

请再次注意:函数的默认参数类型必须是参数类型的子类型:

function log3(x: number | string = 'hello') {
    console.log(x);
}

在上述代码中,函数 log3 的函数参数 x 的类型为可选的联合类型 number | string,但是因为默认参数字符串类型是联合类型 number | string 的子类型,所以 TypeScript 也会检查通过。

剩余参数

在 ES6 中,JavaScript 支持函数参数的剩余参数,它可以把多个参数收集到一个变量中。同样,在TypeScript 中也支持这样的参数类型定义,如下代码所示:

function sum(...nums: number[]) {
    return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2); // => 3
sum(1, 2, 3); // => 6
sum(1, '2'); // ts(2345) Argument of type 'string' is not assignable to parameter of type 'number'

在上述代码中,sum 是一个求和的函数,...nums将函数的所有参数收集到了变量 nums 中,而 nums 的类型应该是 number[],表示所有被求和的参数是数字类型。因此,sum(1, '2') 抛出了一个 ts(2345) 的错误,因为参数 '2' 并不是 number 类型。

如果我们将函数参数 nums 聚合的类型定义为 (number | string)[],如下代码所示:

function sum(...nums: (number | string)[]): number {
    return nums.reduce<number>((a, b) => a + Number(b), 0);
}
sum(1, '2', 3); // 6

那么,函数的每一个参数的类型就是联合类型 number | string,因此 sum(1, '2', 3) 的类型检查也就通过了。

typescript中的常见报错:

  • ts(2322)是一个静态类型检查的错误,在注解的类型和赋值的类型不同的时候就会抛出这个错误
  • ts(2355) :简单来说就是:函数必须有一个返回值(报错翻译:声明类型既不是void也不是any的函数必须返回一个值)
  • ts(2339): 在TypeScript中如果按JS的方式去获取对象属性时,可能会遇到。它表示Typescript在执行代码检查时在该对象没有定义相应属性。解决方法有 —— 直接设置对象为any、对象断言为any、将属性.获取方式改为数组式获取三种
  • ts(2345):参数类型与预期不符
  • ts(2554):参数个数与预期不符

到此这篇关于typescript返回值类型和参数类型的具体使用的文章就介绍到这了,更多相关typescript返回值类型和参数类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈javascript的Touch事件

    浅谈javascript的Touch事件

    在本文深入研究iOS和Android设备提供的触摸事件API,探索一下可以构建哪些类型的应用,给出一些最佳做法,并论及一些使得可触控应用(touch-enabled application)的开发变得更加容易的有用技术。
    2015-09-09
  • 微信小程序实现YDUI的ScrollTab组件

    微信小程序实现YDUI的ScrollTab组件

    这篇文章主要为大家详细介绍了微信小程序实现YDUI的ScrollTab组件,滚动选项卡效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • JavaScript数组迭代器实例分析

    JavaScript数组迭代器实例分析

    这篇文章主要介绍了JavaScript数组迭代器的用法,涉及javascript数组操作的相关技巧,需要的朋友可以参考下
    2015-06-06
  • JavaScript实现短信倒计时60s

    JavaScript实现短信倒计时60s

    本文给大家分享一段实例代码给大家详细介绍了JavaScript实现短信倒计时60s功能,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-10-10
  • JS取request值以及自动执行使用示例

    JS取request值以及自动执行使用示例

    在网页中JS函数自动执行常用三种方法,下面为大家详细介绍下JS取request值以及自动执行使用,需要的朋友可以参考下
    2014-02-02
  • 基于js实现投票的实例代码

    基于js实现投票的实例代码

    这篇文章主要介绍了基于js实现投票的实例代码,三种投票表现效果,个人比较喜欢柱状投票图,具有立体感,感兴趣的朋友可以参考下
    2015-08-08
  • 火狐和ie下获取javascript 获取event的方法(推荐)

    火狐和ie下获取javascript 获取event的方法(推荐)

    下面小编就为大家带来一篇火狐和ie下获取javascript 获取event的方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析

    《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析

    这篇文章主要介绍了Javascript面向对象程序设计单例模式原理与实现方法,结合实例形式分析了《javascript设计模式》中Javascript面向对象单例模式相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • 使用contextMenu插件实现Bootstrap table弹出右键菜单

    使用contextMenu插件实现Bootstrap table弹出右键菜单

    如今Bootstrap这个前端框架已被许多人接受并应用在不同的项目中,其中“开发高效,设备兼容”的特点表现得非常明显。这篇文章主要介绍了使用contextMenu插件实现Bootstrap table弹出右键菜单,需要的朋友可以参考下
    2017-02-02
  • 关于uniapp微信小程序左上角返回按钮的监听详解

    关于uniapp微信小程序左上角返回按钮的监听详解

    uniapp是一个支持多端的技术,因此它是兼容性比较强的,而且速度也很快,下面这篇文章主要给大家介绍了关于uniapp微信小程序左上角返回按钮监听的相关资料,需要的朋友可以参考下
    2022-04-04

最新评论