如何从泛型调用重载函数



让我有两个有几个共同字段的接口和另一个对它们进行概括的接口:

interface IFirst {
common: "A" | "B";
private_0: string;
}
interface ISecond {
common: "C" | "D";
private_1: string;
}
interface ICommon {
common: string;
private_0?: string;
private_1?: string;
}

现在,我想编写一个函数来打印这些接口的实例。我决定使用重载:

function printElement(element: IFirst) : void;
function printElement(element: ISecond): void;
function printElement(element: ICommon) : void {
console.log(element.common);
if (element.private_0)
console.log(element.private_0);
if (element.private_1)
console.log(element.private_1);
}

然后我想写一个函数来打印它们的数组:

function printAll<ElementType extends ICommon>(array: ElementType[]) {
for (const element of array)
printElement(element)
}

然而,这不起作用:

No overload matches this call.   Overload 1 of 2, '(element: IFirst): void', gave the following error.
Argument of type 'ElementType' is not assignable to parameter of type 'IFirst'.
Type 'ICommon' is not assignable to type 'IFirst'.
Types of property 'common' are incompatible.
Type 'string' is not assignable to type '"A" | "B"'.   Overload 2 of 2, '(element: ISecond): void', gave the following error.
Argument of type 'ElementType' is not assignable to parameter of type 'ISecond'.
Type 'ICommon' is not assignable to type 'ISecond'.
Types of property 'common' are incompatible.
Type 'string' is not assignable to type '"C" | "D"'.(2769)

因为ElementType被认为是ICommon实例。例如,编译器试图进行从ICommonIFirst的反向转换,这显然是非法的。那么,我该如何使此函数类型安全呢?

你可以用这样的东西来实现你想要的东西:

interface IFirst {
common: "A" | "B";
private_0: string;
}
interface ISecond {
common: "C" | "D";
private_1: string;
}
type ICommon = IFirst | ISecond;
function printElement(element: ICommon) : void {
console.log(element.common);
if ("private_0" in element) {
console.log(element.private_0);
}
if ("private_1" in element) {
console.log(element.private_1);
}
}
function printAll(array: ICommon[]) {
for (const element of array) {
printElement(element);
}
}

您可以使用Typescript 的接口类型检查中所述的适当功能来改进类型检查

最新更新