Пусть у меня есть два интерфейса, которые имеют несколько общих полей, и другой интерфейс, который их обобщает:
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
экземпляр. Например, компилятор пытается выполнить обратное преобразование из ICommon
в IFirst
, и это, очевидно, недопустимо. Как сделать этот тип функции безопасным тогда?