ts笔记:More on Functions
https://www.typescriptlang.org/docs/handbook/2/functions.html
函数声明
两种:
箭头函数式
1
2
3function greeter(fn: (a: string) => void) {
fn("Hello, World");
}对象式
1
2
3
4
5
6type DescribableFunction = {
(someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log( fn(6));
}这种允许声明函数属性:
1
2
3
4
5
6
7type DescribableFunction = {
description: string;
(someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6));
}允许重载声明
1
2
3
4
5
6
7
8type DescribableFunction = {
(someArg: number): boolean;
(someArg: string): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log( fn(6));
}允许声明构造函数
1
2
3
4
5
6type SomeConstructor = {
new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
return new ctor("hello");
}那么既支持new操作符也支持直接调用的函数,可以利用重载+new声明:
1
2
3
4interface CallOrConstruct {
new (s: string): Date;
(n?: number): number;
}
泛型
为了解决支持不同类型参数的通用函数的声明问题。我们声明一个类型的变量:泛型,用来指代未知的类型。可以理解为一元一次数学方程中的x变量: 2x+1=5, 只要x能满足函数方程就可以,x可以是任何类型。
1 | function firstElement<Type>(arr: Type[]): Type | undefined { |
上例中,泛型Type的具体类型是ts推断出来的,我们没有明确的手动告诉ts。
也可以约束泛型坍塌为具有某些特性的类型。
1 | function longest<Type extends { length: number }>(a: Type, b: Type) { |
更严谨的可以手动指定类型(有时候ts没那么“聪明”可以自己推断出正确的类型)
1 | function combine<Type>(arr1: Type[], arr2: Type[]): Type[] { |
泛型的实践指南
类型参数下移(泛型尽可能下沉到类型的叶子结点, 别太“泛”了)
1 | function firstElement1<Type>(arr: Type[]) { |
这里 第二种写法跟any一样,泛型白用
尽可能减少泛型的数量(能用一个 就不要用两个0
1 | function filter1<Type>(arr: Type[], func: (arg: Type) => boolean): Type[] { |
这里Func就是一个没啥用的泛型
泛型变量应该出现2次(如果这个变量不会用到第二次,那为啥要声明这个泛型呢?)
反例:Str 不如直接用string
1 | function greet<Str extends string>(s: Str) { |
在函数中声明this
大部分时候ts通过推断来判断this指向谁,但是js里this的指向的判定规则还蛮复杂的,ts支持我们告诉他this应该是谁
1 | const user = { |
这种技巧非常适合在回调函数的类型声明中使用,