Проблема Typescript с использованием нескольких типов

Я часами ломал голову над этим, в основном, у меня есть куча разных типов, определенных следующим образом:

export type SharedAPIProps = {
  id: string;
};

export type ButtonAPIProps = SharedAPIProps & {
  type: "paragraph--button";
  field_title: string;
};

export type SlideAPIProps = SharedAPIProps & {
  type: "paragraph--slide";
  field_slides: []
};

export type allAvailableComponents = ButtonAPIProps | SlideAPIProps;


export type ButtonProps = {
  title: string;
}

export type SlideProps = {
  slides: [];
} 

export type allCleanedProps = ButtonProps | SlideProps;

Затем у меня есть функция для преобразования ответа API в чистую версию:

export const toCleanProps = (component: allAvailableComponents): allCleanedProps => {
  const { type } = component;
  
  const convertedProps: allCleanedProps = {} as allCleanedProps;

  switch (type) {
    case "paragraph--button":
      convertedProps.title = component.field_title;
      break;
    case "paragraph--slide":
      convertedProps.slides = component.field_slides;
      break;
  }

  return convertedProps;
}

Проблема в том, что я получаю ошибки машинописного текста для каждого свойства convertedProps. Когда у меня есть только один тип, определенный в allComponentProps, например:

export type allAvailableComponents = ButtonAPIProps;

Я не получаю ошибки в свойствах paragraph--buttonconvertedProps, но, конечно, получаю ошибки в свойствах paragraph--slideconvertedProps.

Новичок в Typescript, так что терпите меня, я, вероятно, упустил что-то простое здесь и перепробовал кучу разных вещей, но ничего не работает.

Сообщение об ошибке о том, что эти реквизиты не существуют для определенных типов.

Вот полный пример: https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcDKALAhlYATAQQAUBJIqCMAZzgF44BvAKDjgEs8AuOKmKNgHYBzANxMAvmKahIsBMlQAhAK4wYEAcTIVqddNlyFS5SjQBkjFvJTcARGBxYhULGAwBadwCNV6gbbFWADM2YAAbPAB9GDYYMOBuXn5hMUkmaXBoeCQUdDCOYC0TXXpMHHwinXNLVhyEuHtHZ1cPdyp8vGAAqxDwqPaCqm4AbQBdCSkZLOtULDCwggA3LDYwrC94gGEIAFtIAWABGBp6FTUNStM4AB88gsvqKQzZbIU4M79ik5qEWPjEviCUQSdJTOR1O6dL56ZisAadIZwMapOCgzLgt5zMKbeJYA54aGnXwaaG3NAdYBfSbo+AAYw0vAQEBxwDxhLgAAp6XsNIcYNwsUsVmsNsBtjyDkcqABKAXzFl4-CEgB8P3pAkZDBmcHEem5+z5gVRrHVjPVi2AsCVVTl2Nx+PZDF1WBoWIVDqqUjhAHdYrSMJy6tKfiaXahGi5mm5PD5zv5OFZWCaNBarQSqgA6GJxVD0fW8o4Z3oRaJ-YBGpNwLy4LAAawrcFpYYaDkjLmjbQptgTleTAlTMGtpgz8OA33zkpgRdCJdHVAbrGrrPrVnE6VYuBgyigAkbKctg-TplSQA

slides — это массив. Попробуйте использовать push
Anindya Dey 22.04.2022 18:55

Извините, опечатка, я обновил SharedProps до SharedAPIProps.

Ben Marshall 22.04.2022 18:58

А также поделитесь сообщениями об ошибках точный, которые вы получаете

derpirscher 22.04.2022 18:58

@T.J.Crowder, другой тип, соответственно обновленный

Ben Marshall 22.04.2022 18:59

@ T.J.Crowder Еще раз извините, еще одна опечатка, я обновил ее. Пример представляет собой гораздо более упрощенную версию и попытался упростить понимание и разъяснение проблемы, с которой я столкнулся.

Ben Marshall 22.04.2022 19:01

@derpirscher обновил сообщение, все ошибки связаны с машинописным текстом, в котором говорится, что реквизиты не были определены для типов.

Ben Marshall 22.04.2022 19:02

Опубликуйте сообщение об ошибке точный. Не описывайте это. Скопируйте и вставьте его. И мне интересно, как что-то вроде const convertedProps: allCleanedProps = {} будет работать без ошибок. Потому что каждый экземпляр allCleanedProps должен иметь свойство title или slides.

derpirscher 22.04.2022 19:05

@T.J.Crowder, это круто, я не знал об этом ресурсе. Я обновил пост со ссылкой на код.

Ben Marshall 22.04.2022 19:05

@derpirscher Смотрите ссылку на код, которую я только что обновил, она показывает точные ошибки, то есть Property 'slides' does not exist on type 'allCleanedProps'.

Ben Marshall 22.04.2022 19:06

Изменение @derpirscher на const convertedProps: allCleanedProps = {} выдает еще одну ошибку: Type '{}' is not assignable to type 'allCleanedProps'.

Ben Marshall 22.04.2022 19:08

Это именно то, что я имел в виду в своем комментарии (потому что этого as allCleanedProps еще не было, когда я разместил этот комментарий

derpirscher 22.04.2022 19:14
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
1
11
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Основная проблема заключается в том, что сужение типа component не сужает тип convertedProps, поэтому TypeScript не знает, что присваивания в порядке.

Вы можете это исправить, создав componentProps в ветках:

export const toCleanProps = (component: allAvailableComponents): allCleanedProps => {
  const { type } = component;

  let convertedProps: allCleanedProps;

  switch (type) {
    case "paragraph--button":
      convertedProps = {
        title: component.field_title,
      };
      break;
    case "paragraph--slide":
      convertedProps = {
        slides: component.field_slides,
      };
      break;
    default:
      throw new Error(`Unexpected 'type'`);
  }

  return convertedProps;
}

Ссылка на игровую площадку

Если задействован процесс очистки, вы можете разделить его на вспомогательные функции:

const cleanButtonProps = (component: ButtonAPIProps): ButtonProps => {
  return {
    title: component.field_title,
  };
};
const cleanSlideProps = (component: SlideAPIProps): SlideProps => {
  return {
    slides: component.field_slides,
  };
};

export const toCleanProps = (component: allAvailableComponents): allCleanedProps => {
  const { type } = component;

  let convertedProps: allCleanedProps;

  switch (type) {
    case "paragraph--button":
      convertedProps = cleanButtonProps(component);
      break;
    case "paragraph--slide":
      convertedProps = cleanSlideProps(component);
      break;
    default:
      throw new Error(`Unexpected 'type'`);
  }

  return convertedProps;
}

Ссылка на игровую площадку

Другие вопросы по теме

Передача vscode во внешние функции
Firebase: Почему мой код использует только первый документ в моей коллекции?
Реагировать на ошибку машинописного текста - элемент неявно имеет любой тип, потому что выражение строки типа не может использоваться для индексирования типа {}
Как получить доступ к вложенным необязательным индексам из интерфейса
Почему машинописный текст не может контекстуально вывести эти типы промежуточного программного обеспечения
Передать конструктор класса как функцию в другом классе
React & clsx: добавьте имя класса, если текущий элемент в сопоставленном массиве является первым из нескольких элементов
Свойство «MathFun» отсутствует в типе «(x?: число, y?: число) => число», но требуется в типе «Func».
Получение строки типа не может быть назначено строке типа для компонента TS в сборнике рассказов
Как ввести useState для файлов?