资讯专栏INFORMATION COLUMN

TypeScript 初识 - 函数

ARGUS / 1709人阅读

摘要:函数类型函数返回值类型我们可以给每个参数添加类型之后再为函数本身添加返回值类型。能够根据返回语句自动推断出返回值类型,所以通常可以省略它匿名函数完整函数类型完整的函数类型包含两部分参数类型和返回值类型。

函数是 JavaScript 的第一等公民,函数在 JavaScript 中可以实现抽象层、模拟类、信息隐藏和模块等等。TypeScript 在一定基础上扩展了函数的功能。

函数类型 函数返回值类型

我们可以给每个参数添加类型之后再为函数本身添加返回值类型。TypeScript 能够根据返回语句自动推断出返回值类型,所以通常可以省略它:

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

// 匿名函数
let myAdd = function(x: number, y: number): number {
    return x + y;
};
完整函数类型

完整的函数类型包含两部分:参数类型和返回值类型。

// (x: number, y: number) => number 为函数的类型
// 其中的 x、y 只是为了增加可读性,只要参数类型是匹配的,无需匹配参数名是否一样
// 参数类型和返回值类型之间使用 => 符号
let myAdd: (x: number, y: number) => number = function(
    x: number,
    y: number
): number {
    return x + y;
};

返回值类型是函数类型的必要部分,函数没有返回值的情况,也必须要指定返回值为 void

推断类型

函数定义的时候,如果赋值语句只有一边指定了语句,TypeScript 编译器会自动识别出类型:

// myAdd has the full function type
let myAdd = function(x: number, y: number): number {
    return x + y;
};

// The parameters `x` and `y` have the type number
let myAdd: (baseValue: number, increment: number) => number = function(x, y) {
    return x + y;
};

这叫做“按上下文归类”,是类型推论的一种。

可选参数和默认参数

默认情况下,TypeScript 会判断传入函数的参数和函数定义的参数是否一致,个数、类型都会进行判断。

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

// An argument for "increment" was not provided.
myAdd(1);
myAdd(1, 2);
// 应有 2 个参数,但获得 3 个。
myAdd(1, 2, 3);

在 TypeScript 中,可以加上 ? 实现可选参数的功能,可选参数必须放在必需参数的前面:

function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + " " + lastName;
    } else {
        return firstName;
    }
}

// Bob
let result1 = buildName("Bob");
// 应有 1-2 个参数,但获得 3 个。
let result2 = buildName("Bob", "Adams", "Sr.");
// Bob Adams
let result3 = buildName("Bob", "Adams");

在定义函数的时候,可以给形参进行赋值作为默认值,仅当不传值或传入的值为 undefined 时,函数会使用这个默认值:

function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

// Bob Smith
let result1 = buildName("Bob");
// Bob Smith
let result2 = buildName("Bob", undefined);

函数的默认值不需要放到必需参数的后面,但是,放在必需参数前面的默认值,只有显式地传递 undefined 时会生效。

剩余参数

在 JavaScript 中,可以使用 arguments 访问传入的所有参数;在 TypeScript 中同样可以使用。

剩余参数将不定数量的参数当作一个数组,表示 0 或多个参数:

// ... 后面加上一个数组,这就是剩余参数
function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

// Bob
console.log(buildName("Bob"));
// Bob Smith Steven
console.log(buildName("Bob", "Smith", "Steven"));

言下之意,剩余参数必须是最后的参数,不能够放到其他参数的前面。

重载

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。在 JavaScript 中,一般是判断传入参数的个数或类型等等情况实现重载。

以 TypeScript 中联合类型的特性,实现 JavaScript 版本的重载:

function reverse(x: number | string): number | string {
    if (typeof x === "number") {
        return Number(
            x
                .toString()
                .split("")
                .reverse()
                .join("")
        );
    }
    return x
        .split("")
        .reverse()
        .join("");
}

// function reverse(x: string | number): string | number
console.log(reverse(123));
console.log(reverse("123"));

上面是是实现重载的一个方法,但是这样实现重载更难懂,不能精确表达。TypeScript 提供更能精确表达的重载方法:

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === "number") {
        return Number(
            x
                .toString()
                .split("")
                .reverse()
                .join("")
        );
    }
    return x
        .split("")
        .reverse()
        .join("");
}

// function reverse(x: number): number (+1 overload)
console.log(reverse(123));
// function reverse(x: string): string (+1 overload)
console.log(reverse("123"));

注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106980.html

相关文章

  • TypeScript 初识 - 变量

    摘要:通常会定义为函数的返回值一个类型的变量是没有生命用处的,因为类型的变量只能赋值为。和有一些区别的,函数没有返回值时返回类型为的方法,即使没有写明语句,也会在函数执行完的时候,隐式地返回一个类型。中新增加的变量声明方式。 类型注解 类型注解使用 :TypeAnnotation 语法。类型声明空间中可用的任何内容都可以用作类型注解。 const num: number = 123; fun...

    dinfer 评论0 收藏0
  • TypeScript 初识 - 接口

    摘要:接口的作用是声明变量的结构和方法,但不做具体的实现。这两个使用场景不同。额外的属性检查从字面上的意思看,其实就是对接口未定义的属性进行检查。上面的例子,定义了接口,它具有索引签名。它不会帮你检查类是否具有某些私有成员。 接口的作用是声明变量的结构和方法,但不做具体的实现。通常,接口会强制对所有成员进行类型检查,包括数量和类型: interface Name { first: s...

    gnehc 评论0 收藏0
  • TypeScript 初识 - 类

    摘要:抽象类抽象类做为其它字类的基类使用,一般不会直接被实例化。抽象类中可以包含具体实现,接口不能。抽象类在运行时是可见的,可以通过判断。接口只能描述类的公共部分,不会检查私有成员,而抽象类没有这样的限制。 一个普通的类 class Greeter { greeting: string; constructor(message: string) { this....

    邹强 评论0 收藏0
  • TypeScript 初识

    摘要:当你陷在一个中大型项目中时应用日趋成为常态,没有类型约束类型推断,总有种牵一发而动全身的危机和束缚。总体而言,这些付出相对于代码的健壮性和可维护性,都是值得的。目前主流的都为的开发提供了良好的支持,比如和。参考资料中文文档 文章博客地址:http://pinggod.com/2016/Typescript/ TypeScript 是 JavaScript 的超集,为 JavaScrip...

    iliyaku 评论0 收藏0
  • TypeScript 初识 - 枚举

    摘要:当满足以下条件时,枚举成员被当作是常数不具有初始化函数并且之前的枚举成员是常数。在这种情况下,当前枚举成员的值为上一个枚举成员的值加。但第一个枚举元素是个例外。枚举成员使用常数枚举表达式初始化。 数字类型枚举 常规枚举的值都是数字类型,因此被称为数字类型枚举: enum Color { Red, Blue, Green } console.log(Color.R...

    molyzzx 评论0 收藏0

发表评论

0条评论

ARGUS

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<