>我正在尝试改进角度函数的DefinitelyTyped定义。它目前看起来像这样:
<T>(array: T[], a_bunch_more_stuff): T[];
使用strictNullChecks
不允许传入,例如T[]|undefined
。我检查了 angular 的来源,它专门检查并允许null
和undefined
。在这些情况下,它只返回第一个参数。这是我能想到的更新.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
不兼容。