1.) Существует различие между методом и объявлением свойства функции:
interface InterfaceA {
doSomething(data: object): boolean; // method declaration
}
interface InterfaceB {
doSomething: (data: object) => boolean; // function as property declaration
}
2.) TS 2.6 введены строгие типы функций, которые обеспечивают более строгую типизацию и многое другое звук функции:
Позиции параметров в типе функции --strictFunctionTypes проверяются , а не бивариантно . более строгая проверка применяется к всем типам функций , кроме тех, которые исходят из объявлений методов или конструкторов .
В общем, это хорошо. В вашем примере InterfaceB
имеет следующий контракт: «Каждая функция, которая может работать с общим object
, совместима». Но вы хотите назначить функцию, которая ожидает Speci c объектов типа { type: string; }
в качестве входных данных. Так что клиент, который использует InterfaceB
, считает, что достаточно передать object
, но реализация doIt
хочет чего-то более конкретного, поэтому вы по праву получаете эту ошибку.
И почему ошибка не возникает случаются с InterfaceA
?
Напротив, методы , такие как doIt
в InterfaceA
, исключены из strictFunctionTypes
по практическим соображениям. Разработчики решили, что система типов не слишком pendanti c со встроенными методами Array
et c. чтобы иметь разумный баланс между правильностью и производительностью.
Итак, в пользу более сильных типов, я бы предпочел следующий тип, который подходит для вашего случая ( sample ):
interface InterfaceB {
doSomething: ((data: { type: string; }) => boolean) | RegExp;
}