Published on

TypeScript - 函数

Authors
  • avatar
    Name
    Deng Hua
    Twitter

目录

函数参数类型注释

In TypeScript, we can specify the type of function parameters in a function definition. This allows Typescript to enforce the types for the values being passed into your function. Typing parameters is just like typing variables!

function square(num) {
  return num * num;
}

当我们声明一个函数,并未对参数num进行赋值时,此时num的类型会被推断为any 此时,对square函数传入任何类型的值都是被允许的。

function square(num) { // 参数 "num" 隐式具有 "any" 类型,但可以从用法中推断出更好的类型。
  return num * num;
}

square(3);
square('string');
square(true);

但我们需要避免隐式any

我们需要给函数的参数注释类型,语法与变量注释类型基本一致。

function square(num: number) {
  return num * num;
}

square(3);
square('string'); // ❌  类型“string”的参数不能赋给类型“number”的参数
square(true); // ❌  类型“boolean”的参数不能赋给类型“number”的参数

square函数的参数被TS约束。

另一个例子:

function greet(person: string) {
  person * person; // ❌ 算术运算左侧必须是 "any"、"number"、"bigint" 或枚举类型
  return `Hi there, ${person}`
}

greet(3); // ❌ 类型“number”的参数不能赋给类型“string”的参数
greet('world');

greet函数的参数被TS约束。

为更多参数进行类型注释

当需要为函数的多个参数进行类型注释时。

const doSomething = (person: string, age: number, isFunny: boolean) => {};

doSomething('john', 50, true);

在调用doSomething函数时,TS还会友好的按顺序提示当前需要的参数类型

const doSomething: (person: string, age: number, isFunny: boolean) => void

参数的默认值

当初始化一个函数时,便可以为参数赋上一个默认值。

function greet(person: string = 'stranger') {
  return `Hi there, ${person}`;
}

greet();
greet('tony');
greet(234) // ❌ 类型“number”的参数不能赋给类型“string”的参数。

函数的返回值类型

函数返回值的隐式推断

typescript也会对函数的返回值进行隐式类型推断

function square(num: number) {
  return num * num;
}

鼠标指向square函数,提示function square(num: number): number,typescript将square函数的返回值推断为了number类型。 原因是,表达式num * num是一个数学操作。

函数返回值的注释

当然,也可以直接对函数的返回值进行类型注释

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

addNums(5, 5);

addNums函数的返回值类型约束为number类型。

反之,有时候我们忘记写return操作符,但如果对返回值进行了类型注释,就可以避免这一错误。

function square(num: number): number {
  num * num;// ❌ A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value
}

square(2);

第2行改写为return num * num;后,错误消失。

良好的编码建议时,总是显式的为函数返回值注释类型,一些具有很多操作的函数,return可能隐藏在很深的代码层级内,显式的返回值注释可以帮助提升代码的可读性。

返回值可能有多种类型

有时候,函数的返回值并不只有一个类型,来看这个例子。

function random(num: number) { // function random(num: number): string | number
  if (Math.random() < 0.5) {
    return num.toString();
  }
  return num;
}

当我们指向random函数,TS会提示我们返回值类型为string | number,这在TS中被称为联合类型,在后续的章节中会提到。

Void 类型

Void is a return type for functions that don't return anything. It means just that - this function is void of any data. Typescript can infer this type fairly well, but sometimes it may want you to annotate a function with a void return explicitly

如果一个函数没有返回值,那这个函数的返回值类型就是void

const nothingReturn = ():void => {}

换言之,如果你声明一个不返回任何值的函数,就可以使用void

const returnVoid = (): void => 0; // ❌ 不能将类型“number”分配给类型“void”

const nothingReturn = (): void => { return 'hi' }; // ❌ 不能将类型“string”分配给类型“void”

在返回值类型为void的函数中,显式或隐式的返回任何内容会被TS检查拦截。

小测验

  1. TS会推断这个这个函数的返回值是什么类型?
function doNothing() {
  2 + 2;
}

答案: void


  1. TS会分配什么类型给这个secondsInDay的返回值?
function secondsInDay() {
  return 24 * 60 * 60;
}

答案: number

Never 类型

The never type represents values that NEVER occur. We might use it to annotate a function that always throws an exception, or a function that never finishes executing. Don't confuse with void - void returns undefined or null, which is technically still a type of value. With never, a function doesn't even finish executing

  1. 作为函数的返回值类型时,表示一个从来不会有返回值的函数。
  2. 一个总是会抛出错误的函数。

推荐阅读文章: A Complete Guide To TypeScript's Never Type