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]

总结

泛型帮助我们在编写时保持代码的灵活性,同时在编译时获得强类型检查的能力。

posted on 2022-03-08 18:52  完美前端  阅读(45)  评论(0)    收藏  举报

导航