У меня есть следующий абстрактный класс
// AbstractFiller.ts
export abstract class AbstractFiller {
public abstract fill(data: number | string | boolean | Date, numberOfFillers: number): string;
}
и несколько подклассов наполнителей
export class WhiteSpacesFiller extends AbstractFiller {
public fill(data: number | string | boolean | Date, numberOfFillers: number): string {
// logic
}
}
export class ZerosFiller extends AbstractFiller {
public fill(data: number | string | boolean | Date, numberOfFillers: number): string {
// logic
}
}
// ...etc
Есть ли способ, которым TS выведет сигнатуру метода из абстрактного класса, чтобы у меня было:
number
из типа data
в подклассе вызовет ошибку нет.Typescript не будет выводить параметры метода из базового класса. Это работает следующим образом: после того, как класс типизирован, он проверяется на совместимость с базовым классом. Это означает, что параметр в производном классе может иметь производный тип (это не правильно, но параметры метода класса относятся бивариантно даже при строгой нулевой проверке).
Одна вещь, которую можно сделать, чтобы уменьшить количество дублирования типов, — это использовать Parameters
с деструктурированием остальных параметров.
export abstract class AbstractFiller {
public abstract fill(data: number | string | boolean | Date, numberOfFillers: number): string;
}
export class WhiteSpacesFiller extends AbstractFiller {
public fill(...[data, numberOfFillers]: Parameters<AbstractFiller['fill']>): string {
return ""
}
}
@RolandJegorov сам мало использовал его ... но он должен работать ... если у вас есть какие-либо проблемы, дайте мне знать. Хотя я уверен, что другого пути нет :)
Хорошо, спасибо. Я оставлю это открытым на день или два, а затем, если ничего не появится, приму ваш ответ. :)
Кроме того, просто чтобы добавить к пункту строгого соблюдения подписи, который я написал выше, кажется, что любой тип аргумента будет действительным, пока он является подмножеством подписи метода абстрактных классов. string | number and string
Надеюсь, я объяснил достаточно понятно.
@RolandJegorov Да, это правда, к сожалению, предотвратить это невозможно.
Извините, если я неправильно понял вопрос, но я думаю, что вы можете решить свою проблему с помощью дженериков, то есть сделать ваш класс AbstractFiller
универсальным.
Это будет выглядеть примерно так:
export abstract class AbstractFiller<T> {
public abstract fill(data: T, numberOfFillers: number): string;
}
export class WhiteSpacesFiller extends AbstractFiller<string> {
public fill(data: string, numberOfFillers: number) {
//logic
return data;
}
}
export class ZerosFiller extends AbstractFiller<number> {
public fill(data: number, numberOfFillers: number) {
return data.toString();
}
}
Эй, спасибо за ответ. Моя цель заключалась в том, чтобы иметь возможность сделать что-то вроде public fill(data, numberOfFillers)
. Кроме того, здесь кажется, что дублирование было перемещено, а не устранено.
Спасибо за ответ. Хм, это интересно. Не знал, что ты так умеешь. Это общепринятый подход? Какие-либо проблемы, с которыми вы столкнулись при использовании этого подхода?