2-1-9 TS 函数

构造函数的表达

type SomeConstructor = {
    new (s: string): String 
}
function fn(ctor: SomeConstructor) {
    return new ctor("hello")
}

const str = fn(String)
console.log(str) // hello

泛型函数

function firstElement<Type>(arr: Type[]): Type {
  return arr[0]
}

关于推导

// map : a -> b
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]

泛型约束

一个巨坑:

function minimumLength<Type extends { length: number }>(
  obj: Type,
  minimum: number
): Type {
  if (obj.length >= minimum) {
    return obj;
  } else {
    return { length: minimum };
  //Type '{ length: number; }' is not assignable to type 'Type'.
  //'{ length: number; }' is assignable to the constraint of type 'Type', but 'Type' could be instantiated with a different subtype of constraint '{ length: number; }'.
  }
}

- 泛型约束:Type 有 length 属性

- 但有{ length } , 不代表是Type

手动指定类型

function combine<Type>(arr1: Type[], arr2: Type[]): Type[] {
  return arr1.concat(arr2);
}

const arr = combine([1, 2, 3], ["hello"]);
// Type 'string' is not assignable to type 'number'.

这种时候可以手动指定类型:

const arr = combine<string | number>([1, 2, 3], ["hello"])

运用泛型的一些规范

对比这一组,哪个更好?

function firstElement1<Type>(arr: Type[]) {
  return arr[0];
}

function firstElement2<Type extends any[]>(arr: Type) {
  return arr[0];
}

划重点:利用好推导(infer)能力,避免用any。

对比下一组,哪个更好?

function filter1<Type>(arr: Type[], func: (arg: Type) => boolean): Type[] {
  return arr.filter(func);
}

function filter2<Type, Func extends (arg: Type) => boolean>(
  arr: Type[],
  func: Func
): Type[] {
  return arr.filter(func);
}

划重点:减少泛型参数的使用(除非有必要)



可选参数

用`?` 描述函数的可选参数。

function myForEach(arr: any[], callback: (arg: any, index?: number) => void) {
  for (let i = 0; i < arr.length; i++) {
    callback(arr[i], i);
  }
}

函数的重载(overloading)

思考下面这段程序:

function add<T> (a : T, b : T ){
    return a  + b
}

// Operator '+' cannot be applied to types 'T' and 'T'.

// a,b不一定可以相加

修改办法:

function isSet<T>(x : any) : x is Set<T> {
		return x instanceof Set
	}	

  function add(a : number, b : number) : number;
	function add(a : string, b : string) : string;
	function add<T>(a : Set<T>, b : Set<T>) : Set<T>;
	function add<T>(a : T, b : T) : T{
			if(isSet<T>(a) && isSet<T>(b)){
				return new Set([...a, ...b]) as any
			}
			return (a as any) + (b as any)
	}
  


	const a = new Set<string>(["apple", "redhat"])
	const b = new Set<string>(["google", "ms"])
	console.log(add(a, b))
	console.log(add(1, 2))
	console.log(add("a", "k")

划重点:利用重载约束跨类型方法的使用

THIS

interface DB {
    exec(sql : string) => any
}

function runSql(this : DB, sql : string){
    this.exec(sql)
}

runSql("select * from user")
// runSql.bind(new DB()).("select * from user")

void vs unknown

函数不返回参数用`void` ,返回的值类型不确定用`unkown`

type voidFunc = () => void;

const f1: voidFunc = () => {
  return true;
};

const f2: voidFunc = () => true;

const f3: voidFunc = function () {
  return true;
}

1

function f1(a: any) {
  a.b(); // OK
}
function f2(a: unknown) {
  a.b();
    
 // Object is of type 'unknown'.
}

unknown可以让代码更安全。

function safeParse(s: string): unknown {
  return JSON.parse(s);
}

1

function fail(msg: string): never {
  throw new Error(msg)
}

rest params

function multiply(n: number, ...m: number[]) {
  return m.map((x) => n * x);
}
// 'a' gets value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值