Как типизировать объект в зависимости от указанного значения в свойстве?
Есть общий интерфейс(SpinnerInterface) в котором перечислены все допустимые свойства объекта.
Но свойство(statusCheck) должно быть обязательным только в случае если type будет указан как progressLoading
interface SpinnerInterface{
fillParent: boolean;
type: SpinnerType;
statusCheck: StatusProgress; // только для type:progressLoading
}
enum SpinnerType {
blockedPage,
progressLoading
}
Типизация через Omit исключает свойство для всех свойств.
type ExcludeStatus = Omit<SpinnerInterface, 'statusCheck'>;
Я предполагаю что нужно добавить еще какую то обработку перед ExcludeStatus но я незнаю в какую сторону нужно копать(гуглить).
Буду рад вашим идеям/предположениям/ссылкам. Большое спасибо за помощь.
Ответы (1 шт):
Можно создать общий тип с кастингом св-ва + несколько типов, которые расширяют базовый и там прописать условие для динамических полей
enum SpinnerType {
BASE = 'base',
PROGRESS_LOADING = 'progressLoading',
}
interface StatusProgress {
loading: boolean;
}
// Базовый тип
interface Spinner<T = SpinnerType> {
fillParent: boolean;
type: T;
}
interface SpinnerBase extends Spinner<SpinnerType.BASE> {};
interface SpinnerWithProgress extends Spinner<SpinnerType.PROGRESS_LOADING> {
statusCheck: StatusProgress;
}
type Spinners = SpinnerBase | SpinnerWithProgress;
// Тут все ок без св-ва statusCheck
const spinnerBase: SpinnerBase = {
type: SpinnerType.BASE,
fillParent: true,
}
// Тут ошибка, что statusCheck св-ва нет
const spinnerWithProgressWrong: SpinnerWithProgress = {
type: SpinnerType.PROGRESS_LOADING,
fillParent: false,
}
const spinnerWithProgressRight: SpinnerWithProgress = {
type: SpinnerType.PROGRESS_LOADING,
fillParent: false,
statusCheck: { loading: false }
}
Из плюсов, в switch/case по type тип будет автоматические внутри case определяться)