TypeScript函数
针对函数的部分,做了如下的回顾
函数类型表达式
用于描述函数参数类型、返回值。
1 | function greeter(fn: (a: string) => void) { |
调用签名
用于用属性描述函数可调用的东西,可以在对象类型中编写调用签名
1 | type DescribableFunction = { |
与函数类型表达式相比,在参数列表和返回值之间使用了:
而不是=>
构造签名
通过在调用签名前添加关键字new
来编写构造签名
1 | type SomeConstructor = { |
泛型函数
描述某一类参数、返回值类型相同的函数。当想要描述参数与返回值的关系时,可通过泛型指定
1 | function firstElement<Type>(arr: Type[]): Type | undefined { |
推断
ts可以自动根据参数类型推断出返回值的类型
1 | function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] { |
TypeScript 可以推断Input类型参数的类型(从给定的string数组),以及Output基于函数表达式的返回值的类型参数 ( number)
约束
指的就是对类型或属性的限制。在 想关联两个值,但只能对某个值的子集进行操作 时可以用到
1 | function longest<Type extends { length: number }>(a: Type, b: Type) { |
上述的extends
就是子句,用于当我们无法直接操作Type类型的情况
还需要注意一个常见的错误:函数承诺返回与传入相同类型的对象,而不仅仅是与约束匹配的某个对象。
可选参数
通过?
声明可选参数。可选参数可以接收undefined。
可以声明默认参数
fn(x=10)
回调中的可选参数
为回调编写函数类型时,切勿编写可选参数,除非打算在不传递该参数的情况下调用该函数
1 | function myForEach(arr: any[], callback: (arg: any, index?: number) => void) { |
上述报错显示i可能为undefined,但实际是不可能出现的错误
函数重载
在 TypeScript 中,我们可以通过编写重载签名来指定一个可以以不同方式调用的函数。为此,请编写一些函数签名(通常是两个或更多),然后是函数的主体:
1 |
|
前两个签名称为重载签名。然后,我们编写了一个具有兼容签名的函数实现。函数有一个实现签名,但是这个签名不能直接调用。即使我们在必需的参数之后编写了一个带有两个可选参数的函数,也不能用两个参数调用它!
实现签名还必须与重载签名兼容
尽可能使用联合类型的参数而不是重载
this 在函数中声明
JavaScript 规范声明你不能有一个名为 this 的参数,因此 TypeScript 使用该语法空间让你在函数体中声明 this 类型
1 | const user = { |
其他的一些类型
- void
无返回值 - unknown
表示任何值,类似与any,但比any更安全。因为用unknown做任何事情都是不合法的 - never
示从未观察到的值,意味着达不到的意思。在函数返回类型中,这意味着函数抛出异常或终止程序的执行 - Function
全局类型Function描述了 JavaScript 中所有函数值上的属性,如bind、call、apply和其他属性 - object
特殊类型object是指任何不是原始值(string、number、bigint、boolean、symbol、null或undefined)的值。这与空对象类型 { }不同,也与全局类型不同Object。很可能永远不会使用Object
object不是Object。一直用object!
剩余参数和参数
rest 参数出现在所有其他参数之后,并使用…语法
1 | function multiply(n: number, ...m: number[]) { |
通常,TypeScript 并不假定数组是不可变的。即展开运算符扩展的是一个以上的参数,而不是具体的几个参数
1 | const args = [8, 5]; |
错误提示需要两个参数,正在用“0或更多”参数调用Math.atan2()。
这种情况的最佳解决方案取决于代码,但一般来说,const上下文是最直接的解决方案
1 | // Inferred as 2-length tuple |
通过使用as const,将args数组变为了定长的只读数组,防止了报错
参数解构
1 |
|
TypeScript函数