Почему TypeScript не применяет подпись интерфейса?

#typescript

Вопрос:

Итак, у меня есть следующий интерфейс:

 interface DoStuffInterface {
    doStuff(value: string | number): string | number;
}
 

Почему при реализации этого интерфейса TS не применяет подпись?

 class NumberStuff implements DoStuffInterface {
    public doStuff(value: number): string | number { // <====== missing: | string
        return value;
    }
}

class StringStuff implements DoStuffInterface {
    public doStuff(value: string): string | number { // <====== missing: | number
        return value.toLowerCase();
    }
}
 

Это легко разбивается с помощью чего-то подобного:

 var numberStuff = new NumberStuff();
var stringStuff = new StringStuff();

function run(thing: DoStuffInterface): void {
    console.log(thing.doStuff(42));
}

run(numberStuff);
run(stringStuff); // <====== this fails, due to: `42.toLowerCase()`
 

Итак, почему TS не применяет NumberStuff amp; StringStuff , чтобы иметь правильную подпись? Если бы подпись была правильно установлена, это была бы ошибка во время компиляции, вместо этого вы получите ошибку во время выполнения.

Мне не хватает какого-то флага конфигурации? Или это ожидаемое поведение?

Вот полный пример

Комментарии:

1. Просто не раскрывайте свой вопрос, это ошибки при компиляции: type doStuff = (value: string | number) => string | number; const doNumberStuff: doStuff = (value: number) => value;

Ответ №1:

TLDR для включения метода изменения желаемого поведения в свойство:

 interface DoStuffInterface {
    doStuff: (value: string | number) => string | number;
}
 

Игровая площадка


Для интерфейсов в соответствии со строгими типами функций положения параметров типа функций проверяются контравариантно (для «опоры функции»), а не двумерно (для метода)

Более строгая проверка применяется ко всем типам функций, за исключением тех, которые возникают в объявлениях методов или конструкторов. Методы исключаются специально для обеспечения того, чтобы общие классы и интерфейсы (такие как Array<T> ) продолжали в основном ковариантно связываться.