Правила совместимости между сигнатурами перегрузки и сигнатурой реализации гораздо более мягкие, чем для назначения.
В этом случае вы пытаетесь назначить функцию, которая может вернуть null
функции, которая имеетперегрузка, которая запрещает возврат нуля ((value: number): number;
).Компилятор по праву найдет это беспокойство.Что касается перегрузок, поскольку сигнатуры и реализация написаны как единое целое, компилятор предполагает «Вы знаете, что делаете» (правильно или нет).
Вы можете обойти это несколькими способами:
Вы можете использовать утверждение типа, хотя вы потеряете большинство проверок типов для реализации, совместимости подписи:
type INumberConverter = {
(value: number): number;
(value: null): null;
};
const decimalToPercent = ((value: number | null): number | null => {
if (!value) {
return null;
}
return value * 100;
}) as INumberConverter;
Вы также можете использовать обычный function
и захватывать this
, как в старомES5
дней, хотя это решение означает дублирование большой части сигнатуры функции:
type INumberConverter = {
(value: number): number;
(value: null): null;
};
class X {
decimalToPercent: INumberConverter;
multiper = 100;
constructor() {
let self = this;
function decimalToPercent(value: number): number;
function decimalToPercent(value: null): null;
function decimalToPercent(value: number | null): number | null {
if (!value) {
return null;
}
// use self
return value * self.multiper;
};
this.decimalToPercent = decimalToPercent;
}
}
Или, возможно, самое простое решение - использовать bind
в конструкторе и написать функцию как обычный метод:
class X {
decimalToPercent(value: number): number;
decimalToPercent(value: null): null;
decimalToPercent(value: number | null): number | null {
if (!value) {
return null;
}
return value * this.multiper;
};
multiper = 100;
constructor() {
this.decimalToPercent = this.decimalToPercent.bind(this);
}
}