TypeScript学习(三):Handbook -> More on Functions

680 阅读3分钟

构造函数 -> Construct Signatures

interface CallOrConstruct {  new (s: string): Date;  (n?: number): number;}function fn(ctor: CallOrConstruct) {  return new ctor("hello");}

泛型函数

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

inference -> 推断

TS 会根据

function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {  return arr.map(func);}
// Parameter 'n' is of type 'string'// 'parsed' is of type 'number[]'const parsed = map(["1", "2", "3"], (n) => parseInt(n));

Constraints -> 约束

extends

有时候,当想关联两个值。但是,只能操作值的部分子集。

function longest<Type extends { length: number }>(a: Type, b: Type) {  if (a.length >= b.length) {    return a;  } else {    return b;  }}

约束值

下面代码会出错,原因是函数会保证与传入参数相同类型的对象,而不是一种符合约束的的对象。

function minimumLength<Type extends { length: number}>(
    obj: Type, 
    minimum: number
): Type{
    if (obj.length >= minimun){
        // 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; }'.
        return obj
    }else{
        return { length: minimum }
    }
}

Specifying Type Arguments

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

//  TS 会自动推断两个Type都为 number, 函数报错
const arr = combine([1, 2, 3], ["hello"]);

//  解决方法
const arr = combine<string | number>([1, 2, 3], ["hello"]);

Push Type Parameters Down

在泛型中,避免过度使用约束

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

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

// return number
const a = firstElement1([1,2,3])
// Type extends any return any
const b = firstElement2([1,2,3])

Use Fewer Type Parameters

第二种写法是没有必要的,extends其实是用泛型变量连接两个值,这两个值会“共享”这个泛型变量。

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)
}

原文:We’ve created a type parameter Func that doesn’t relate two values. That’s always a red flag, because it means callers wanting to specify type arguments have to manually specify an extra type argument for no reason. Func doesn’t do anything but make the function harder to read and reason about!

Type Parameters Should Appear Twice

Sometimes we forget that a function might not need to be generic:

function greet(s: Str) {

    console.log("Hello, " + s);

}

Type Parameters Should Appear Twice

泛型是为了关联多个值的类型,如果类型参数在函数中,只出现一次,最好别使用。

Remember, type parameters are for relating the types of multiple values. If a type parameter is only used once in the function signature, it’s not relating anything.

Optional Parameters

? 符号表示可选参数,下方函数可以传入undefined 或者 不传 或者一个number

declare function f(x?: number): void;
f();f(10);

f(undefined);

在回调函数中,index 是 optional;但是调用的时候,cb中传入了i,会报错,使用 i! 可以避免。

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

myForEach([1,2,3], (a, i) => {
    console.log(i!.toFixed())

    // 报错 Object is possibly 'undefined'.
    // console.log(i.toFixed())
})

但是,如果cb中传入2个参数,调用的时候只传入1个,是不会报错的。这种情况下,TS 的行为与 JS 一致。

函数重载 Function Overloads

重载的时候,形参的类型一定要确定,不能模糊,如下。

function len(s: string): number;
function len(arr: any[]): number;
function len(x: any) {  return x.length;}
len(""); // OKlen([0]); // OK
len(Math.random() > 0.5 ? "hello" : [0]); // 报错,因为值不一样

在函数中声明 this

TS 会推导 this 的值

interface User{
    id: number;
    admin: boolean
}

interface DB {
    filterUsers(filter: (this: User) => boolean): User[];
}

declare const getDB: () => DB;const db = getDB();
const admins = db.filterUsers(function(this:User) {
    return this.admin
})

其他类型

void: void并不是undefined

object:TS中object指的是非基础类型的其他对象。并非是直面量{}

unknow:和any很像,但是更安全,因为不能对unknown类型做任何操作

never:在函数中,never表示函数会报错或者终止执行;也表示联合类型中穷举完毕,没有其他类型了

Function: Funcion类型的函数执行返回 any 类型,更多:

参考

www.typescriptlang.org/docs/handbo…