Как обрабатывать разные типы под одним родителем в React typescript

#reactjs #typescript #redux

#reactjs #typescript #redux

Вопрос:

Я новичок в React / Typescript и столкнулся с проблемой… Я пытаюсь создать клон Google Forms.

Моя идея состоит в том, чтобы иметь interface для каждого типа вопроса, например:

 interface ShortText {
    question: string;
    placeholder: string;
}

interface MultipleChoice {
    question: string;
    placeholder: string;
    choices: string[];
}
 

И так далее для каждого типа. Далее мне нужно сохранить список всех этих вопросов (относящихся ко всем разным интерфейсам) в моем хранилище. Но я не могу этого сделать, потому что все они имеют разные интерфейсы!

Как я мог это сделать?

Ответ №1:

Типы объединения могут работать здесь: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#union-types

Например, используя различающие объединения: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions

 interface ShortText {
    kind: "shortText";
    question: string;
    placeholder: string;
}

interface MultipleChoice {
    kind: "multipleChoice";
    question: string;
    placeholder: string;
    choices: string[];
}

// Create a type which represents only one of the above types
// but you aren't sure which it is yet.
type Question =
  | ShortText
  | MultipleChoice;

...

let questions: Question[];

...

switch (question.kind) {
    case "shortText":
      ...
    case "multipleChoice":
      ...
}
 

Комментарии:

1. Привет, спасибо, это очень полезно! В чем разница между типом и интерфейсом и почему вы использовали тип для Question и интерфейс для ShortText и MultipleChoice ?

2. @RahulRentash interface ShortText { ... } является более понятным синтаксисом type ShortText = { ... } и type может использоваться для создания более сложных типов, таких как типы объединения 🙂

3. Ах, я понимаю… и последнее: если бы у меня был список всех kind s ( const kinds: string[] = ["shortText", ...] , как я мог быть уверен, что kind он находится в этом списке? Спасибо!

4.Не уверен, может быть, вы могли бы определить тип строкового литерала type QuestionKind = "shortText" | "multipleChoice"