Почему тип функции не подходит для функционального интерфейса?
interface IGetObjectCallback {
(data: any): void;
(data: any, elapsedTime: number): void;
}
interface Fetcher extends IGetObjectCallback {
getObject(done: IGetObjectCallback): void;
}
let a:Fetcher = ('data',3) => {
}
Почему при таком коде получаю ошибку несоответствия типов при присваивании?
Ответы (1 шт):
Данный вопрос можно разбить на две части:
- как работает перегрузка в функциональном интерфейсе
- добавление в этот интерфейс метода
Как работает перегрузка в функциональном интерфейсе
Если в функциональном интерфейсе указано несколько перегрузок, как в примере в вопросе
interface IGetObjectCallback {
(data: any): void;
(data: any, elapsedTime: number): void;
}
Это значит, что функция должна удовлетворять обоим этим определениям.
В случае с
let a:IGetObjectCallback = ('data',3)=>{}
Передаваемая функция не совпадает ни с одним. Если добавить в определение типы
let a:IGetObjectCallback = (data:'data',elapsedTime:3)=>{}
Ошибка станет понятнее: тип 3 не совместим с типом number, так как по интерфейсу могут передать любое число, а функция может принять только 3.
Если заменить типа на number
let a:IGetObjectCallback = (data:'data', elapsedTime:number)=>{}
Все еще не будет соответствия интерфейсу, так как передаваемая функция принимает строго два параметра, тогда как в интерфейсе указано, что он должна уметь принимать и всего один параметр. В этом случае решить можно с помощью значения по умолчанию
let a:IGetObjectCallback = (data:'data', elapsedTime:number = 0)=>{}
Теперь передаваемая функция удовлетворяем всем условиям и присваивается без ошибок.
Добавление в этот интерфейс метода
Я не нашел нормального способа с помощью литерала создать функцию со статическим методом.
Поэтому пока единственный вариант, который я вижу - сделать наличие метода опциональным. В этом случае можно создать литерал функции без него и далее просто его присвоить:
Например:
let b: Fetcher = (data: any, elapsedTime: number = 0) => { console.log(data) }
b.getObject = (data: any, elapsedTime: number = 0) => { console.log(data) }
Интерфейс в этом случае будет выглядеть так:
interface Fetcher extends IGetObjectCallback {
getObject?(done: IGetObjectCallback): void;
}