Typescript Declaration: T|null|undefined 返回你传入的类型



>我正在尝试改进角度函数的DefinitelyTyped定义。它目前看起来像这样:

<T>(array: T[], a_bunch_more_stuff): T[];

使用strictNullChecks不允许传入,例如T[]|undefined。我检查了 angular 的来源,它专门检查并允许nullundefined。在这些情况下,它只返回第一个参数。这是我能想到的更新.d.ts文件的最佳方法:

<T>(array: T[], a_bunch_more_stuff): T[];
<T>(array: T[]|null, a_bunch_more_stuff): T[]|null;
<T>(array: T[]|undefined, a_bunch_more_stuff): T[]|undefined;
<T>(array: T[]|null|undefined, a_bunch_more_stuff): T[]|null|undefined;

这将在返回值上保持正确的联合。例如,如果我们只使用最后一行,而您在T[]|null中传递,则返回值将为T[]|null|undefined,这太宽了。有没有更简洁的方式来表达这四行,同时保持它们良好的行为?

是的,您可以声明返回与其第一个参数完全相同的类型的函数,并使用两个泛型参数来表达对参数类型的约束,如下所示:

function x<T, Q extends T[] | null | undefined>(a: Q, ...args: any[]): Q {
    return a;
}
class C {
    a1: string[];
    a2: string[] | null;
    a3: string[] | undefined;
    a4: string[] | null | undefined;
    f() {
        // check all permutations
        this.a1 = x(this.a1);
        this.a2 = x(this.a2);
        this.a3 = x(this.a3);
        this.a4 = x(this.a4);
        this.a1 = x(this.a2);  // disallowed
        this.a1 = x(this.a3);  // disallowed
        this.a1 = x(this.a4);  // disallowed
        this.a2 = x(this.a1);
        this.a2 = x(this.a3);  // disallowed
        this.a2 = x(this.a4);  // disallowed
        this.a3 = x(this.a1);
        this.a3 = x(this.a2);  // disallowed
        this.a3 = x(this.a4);  // disallowed
        this.a4 = x(this.a1);
        this.a4 = x(this.a2);
        this.a4 = x(this.a3);
        this.a4 = x(this.a4);
    }
}

请注意,对于strictNullChecks,这使得T[] | undefined与对于实际代码来说可能过于严格的T[] | null不兼容。

最新更新