09 - TS 关于函数的补充
函数的补充
构造函数的表达
/*
定义构造函数类型
其中 'new' 表示构造函数
s: int 是构造函数的参数类型
返回值类型为 String
*/
type SomeConstructor = {
new (s: int): String
}
/*
函数 fn 接收一个构造函数作为参数,并使用该构造函数创建一个新对象。
*/
function fn(ctor: SomeConstructor) {
return new ctor("hello");
}
const str = fn(String);
console.log(str); // 输出: hello
泛型函数
/*
泛型函数定义,返回数组的第一个元素。
Type 是一个泛型参数,代表任意类型。
*/
function firstElement(arr: Type[]): Type {
return arr[0];
}
/*
非泛型版本,使用 'any' 类型。这种写法失去了类型的保证。
*/
function firstElement(arr: any): any {
return arr[0];
}
关于推导
/*
使用泛型和推导来映射数组的值。
Input 和 Output 都是泛型参数,代表输入和输出的类型。
*/
function map<Input, Output>(
arr: Input[],
func: (arg: Input) => Output): Output[] {
return arr.map(func);
}
const parsed = map(["1", "2", "3"], (n) => parseInt(n)); // 输出: [1,2,3]
泛型约束
/*
使用泛型约束确保对象具有 length 属性。
但此函数的返回类型可能与输入的类型不符。
*/
function minimumLength(
obj: Type,
minimum: number
): Type {
if (obj.length >= minimum) {
return obj;
} else {
return { length: minimum };
// 错误: Type '{ length: number; }' is not assignable to type 'Type'.
}
}
手动指定类型
/*
组合两个数组,但由于类型不匹配会报错。
*/
function combine(arr1: Type[], arr2: Type[]): Type[] {
return arr1.concat(arr2);
}
/*
手动指定泛型参数来解决类型不匹配的问题。
*/
const arr = combine([1, 2, 3], ["hello"]);
函数的重载(overloading)
/*
定义了一个加法函数,但由于不确定输入的类型,所以使用函数重载来约束可能的输入和输出类型。
*/
function isSet(x: any): x is Set {
return x instanceof Set;
}
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: Set, b: Set): Set;
function add(a: T, b: T): T {
if(isSet(a) && isSet(b)){
return new Set([...a, ...b]) as any;
}
return (a as any) + (b as any);
}
const a = new Set(["apple", "redhat"]);
const b = new Set(["google", "ms"]);
console.log(add(a, b));
console.log(add(1, 2));
console.log(add("a", "k"));
THIS
/*
在接口中定义一个方法,然后在函数中使用 'this' 来约束函数的调用者。
*/
interface DB {
exec(sql: string): any;
}
function runSql(this: DB, sql: string) {
this.exec(sql);
}
runSql.bind(new DB()).("select * from user");
void vs unknown
/*
对于不返回任何值的函数,使用 'void' 类型。
对于可能返回任何类型的函数,使用 'unknown' 类型。
*/
function safeParse(s: string): unknown {
return JSON.parse(s);
}
function fail(msg: string): never {
throw new Error(msg);
}
rest params
/*
使用剩余参数来定义一个接受不定数量参数的函数。
*/
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x);
}
const a = multiply(10, 1, 2, 3, 4); // 输出: [10, 20, 30, 40]
总结
泛型帮助我们在编写时保持代码的灵活性,同时在编译时获得强类型检查的能力。
浙公网安备 33010602011771号