TypeScript系列 --- 函数和字面量

400 阅读4分钟

函数

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。

// 具名函数
function add(x, y) {
    return x + y;
}

// 匿名函数
let myAdd = function(x, y) { return x + y; };

函数类型

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

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

因为TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略函数的返回值类型

函数类型包含两部分:参数类型和返回值类型

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

推断类型

如果在等式的一侧带有类型,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会默认假设函数的每个参数都是必须的

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

let result1 = buildName("Bob");                  // error, too few parameters
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");         // ah, just right

JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。 在TypeScript里我们可以在参数名旁使用?实现可选参数的功能

可选参数必须跟在必须参数后面

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

let result1 = buildName("Bob");  // works correctly now
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");  // ah, just right

在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined

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

let result1 = buildName("Bob");                  // works correctly now, returns "Bob Smith"
let result2 = buildName("Bob", undefined);       // still works, also returns "Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result4 = buildName("Bob", "Adams");         // ah, just right

在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。 也就是说可选参数与末尾的默认参数共享参数类型

function buildName(firstName: string, lastName?: string) {
    // ...
}

function buildName(firstName: string, lastName = "Smith") {
    // ...
}

// 上面两个函数的类型都是 (firstName: string, lastName?: string) => string

与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入undefined值来获得默认值

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

let result1 = buildName("Bob");                  // error, too few parameters
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");         // okay and returns "Bob Adams"
let result4 = buildName(undefined, "Adams");     // okay and returns "Will Adams"

剩余参数

你想同时操作多个参数,或者你并不知道会有多少参数传递进来的时候,就可以使用剩余参数

function buildName(firstName: string, ...restOfName: string[]) {
  return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器创建参数数组,名字是你在省略号(...)后面给定的名字,你可以在函数体内使用这个数组。

字面量类型

一个字面量是一个集体类型中更为具体的一种子类型

目前 TypeScript 中有三种可用的字面量类型集合,分别是:字符串、数字和布尔值。通过使用字面量类型,你可以规定一个字符串、数字或布尔值必须含有的确定值。

// name的类型是 ‘Klaus’ 不是string
let name = 'Klaus'
name = 'Alex' // error

字面量类型可以通过联合联系、类型守卫、类型别名来结合实际字符串值。通过这些特性,我们可以获取一种字符串并使其有类似枚举(enum)的行为。

type Easing = "ease-in" | "ease-out" | "ease-in-out";

class UIElement {
  animate(dx: number, dy: number, easing: Easing) {
    if (easing === "ease-in") {
      // ...
    } else if (easing === "ease-out") {
    } else if (easing === "ease-in-out") {
    } else {
      // It's possible that someone could reach this
      // by ignoring your types though.
    }
  }
}

let button = new UIElement();
button.animate(0, 0, "ease-in");
button.animate(0, 0, "uneasy");
// Error: Argument of type '"uneasy"' is not assignable to parameter of type 'Easing'.

数字字面量类型

数字字面量类型经常用来描述配置值

interface MapConfig {
  lng: number;
  lat: number;
  tileSize: 8 | 16 | 32;
}

setupMap({ lng: -73.935242, lat: 40.73061, tileSize: 16 });