TypeScript 的函数类型
函数的类型声明,需要在声明函数时,给出参数的类型和返回值的类型。
// 写法一
function hello(text: string): void {
console.log("hello " + text);
}
// 写法二
const hello: (text: string) => void = function (text) {
console.log("hello " + text);
};
// 写法三:函数类型里面的参数名与实际参数名,可以不一致。 content / text
let fn: (content: string) => string;
fn = function (text: string) {
return text;
};
// 写法四:常用
type MyFn = (text: string) => void;
const hello: MyFn = function (text) {
console.log("hello " + text);
};
// 写法五: 非箭头函数类型
function hello(fn: (a: string) => void): void {
fn("world");
}
// 写法六:初级不常见 可暂时省略 适用在函数本身存在属性的时候
let add: { (a: number, b: number): number };
add = function (a, b) {
return a + b;
};
示例中,函数hello()
在声明时,需要给出参数text
的类型(string),及返回值的类型(void
),此处void
类型表示没有返回值
没有
return
语句,TypeScript 会推断出函数hello()
没有返回值。
如果一个变量要套用另一个函数类型,有一个技巧,可以使用typeof
运算符。
function add(a: number, b: number) {
return a + b;
}
const myAddFn: typeof add = function (a, b) {
return a + b;
};
例子
type Person = { name: string };
const arr = ["Jack", "Rose", "Peter"];
const people = arr.map((name): Person => ({ name }));
上面示例中,
Person
是一个类型别名,代表一个对象,该对象有属性name
。
map()
方法的参数是一个箭头函数(name):Person => ({name})
,该箭头函数的参数name
的类型省略了,因为可以从map()
的类型定义推断出来,箭头函数的返回值类型为Person
。相应地,变量people
的类型是Person[]
。
至于箭头后面的({name})
,表示返回一个对象,该对象有一个属性name
,它的属性值为变量name
的值。这里的圆括号是必须的,否则(name):Person => {name}
的大括号表示函数体,即函数体内有一行语句name
,同时由于没有return
语句,这个函数不会返回任何值。
参数默认值
设置默认值的参数,就是可选的。如果不传入该参数,它就会等于默认值。
function add(a: number = 0, b: number = 0): number {
return a + b;
}
add();
上面示例中,参数a
和b
的默认值都是0
,调用add()
时,这两个参数都是可以省略的。这里其实可以省略x
和y
的类型声明,因为可以从默认值推断出来。
function add(a = 0, b = 0) {
return a + b;
}
参数解构
函数参数如果存在变量解构,类型写法如下。
function add({ a, b, c }: { a: number; b: number; c: number }) {
console.log(a + b + c);
}
参数解构可以结合类型别名(type 命令)一起使用
type ABC = { a: number; b: number; c: number };
function add({ a, b, c }: ABC) {
console.log(a + b + c);
}
rest 参数
例子一:参数m
就是 rest 类型,它的类型是一个数组。
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x);
}
例子二:rest 参数可以与变量解构结合使用。
function repeat(...[str, times]: [string, number]): string {
return str.repeat(times);
}
void 类型
void 类型表示函数没有返回值。
void 类型允许返回
undefined
或null
。
函数的运行结果如果是抛出错误,也允许将返回值写成void
。
!!!重点!!!
type voidFn = () => void;
const f: voidFn = () => {
return 666;
};
这样使用并不会报错,
但是如果使用这个函数的返回值,就会报错
type voidFn = () => void;
const f: voidFn = () => {
return 666;
};
f() + 888; // 报错
never 类型
never
类型表示肯定不会出现的值。它用在函数的返回值,就表示某个函数肯定不会返回值,即函数不会正常执行结束。
使用情景:
(1) throw error
function fail(msg: string): never {
throw new Error(msg);
}
如果显式用
return
语句返回一个 Error 对象,返回值就不是 never 类型。
(2) 无限循环函数 省略
函数重载
说明: 一个函数可以接受不同类型或者数量的参数,根据参数的不同,会有不同的函数行为。
实现方法: 逐一定义每一种情况的类型。
Todo:
例子:
构造函数
例子:
// 第一种情况
class Animal {
numLegs: number = 4;
}
type AnimalConstructor = new () => Animal;
function create(c: AnimalConstructor): Animal {
return new c();
}
const a = create(Animal);
// 第二种情况 类型 F 就是一个构造函数
type F = {
new (s: string): object;
};
// 第三种 F 既可以当作普通函数执行,也可以当作构造函数使用。
type F = {
new (s: string): object;
(n?: number): number;
};
async 函数
async 函数的的返回值是一个 Promise 对象。
const p: Promise<number> = 666;
async function fn(): Promise<number> {
var i = await p;
return i + 1;
}