Передача потомка класса generi c завершается неудачно в шаблоне стратегии - PullRequest
1 голос
/ 26 апреля 2020

Я пытаюсь реализовать шаблон стратегии с использованием обобщений в Typescript. Идея состоит в том, чтобы иметь один маппер с ключом всех возможных типов, тогда значение будет иметь все вопросы (которые будут отображаться с React), необходимые для этого конкретного типа (позже он будет расширен, чтобы также иметь валидации и другие вещи, связанные с этим тип).

Это объекты для применения шаблона к

export interface Book {
    id: string;
    type: string;
    title: string;
    author: string;
}

export interface Novel extends Book {
    genre: string;
}

Это набор для вопросов

export interface BookQuestionProps<T> {
    book: T;
}

//implementation
export const titleQuestion: React.FunctionComponent<BookQuestionProps<Book>> = ({
    book
}: BookQuestionProps<Book>) => {
    return <input type="text" value={book.title} />
}

export const genreQuestion: React.FunctionComponent<BookQuestionProps<Novel>> = ({
    book
}: BookQuestionProps<Novel>) => {
    return <input type="text" value={book.genre} />
}

Это основная часть шаблона

export interface BookMapperStrategy<T> {
    questions: React.FunctionComponent<BookQuestionProps<Book>>[]
}

export interface BookTypeMapperStrategy<T> {
    [type: string]: BookMapperStrategy<T>;
}

После всех этих настроек реализация будет выглядеть примерно так:

//specific strategy for novel
const novelQuestions: React.FunctionComponent<BookQuestionProps<Novel>>[] = [
    titleQuestion,
    genreQuestion
]

const novelMapperStrategy: BookMapperStrategy<Novel> = {
    questions: novelQuestions
}

// setup strategy pattern mapper
const bookTypeMapperStrategy: BookTypeMapperStrategy<Book> = {
    novel: novelMapperStrategy,
}

//print questions
const novel: Novel = {
    id: '',
    type: 'novel',
    title: '',
    author: '',
    genre: ''
}

bookTypeMapperStrategy[novel.type].questions.map((question) => {
    React.createElement(question, {
        novel
    })
})

Затем Typescript выдаст мне ошибку компиляции на novelQuestions, особенно при установке titleQuestion в массиве следующее:

Type 'FunctionComponent<BookQuestionProps<Book>>' is not assignable to type 'FunctionComponent<BookQuestionProps<Novel>>'.
  The types of 'propTypes.book' are incompatible between these types.
    Type 'Validator<Book>' is not assignable to type 'Validator<Novel>'.
      Type 'Book' is not assignable to type 'Novel'.ts(2322)

Я попытался изменить интерфейс на объединение типов, но это дает еще больше ошибок.

Я бы подумал, что, поскольку Novel является потомком Book, передача titleQuestion типа React.FunctionComponent<BookQuestionProps<Book>> в состав React.FunctionComponent<BookQuestionProps<Novel>> будет работать, потому что Book является родителем из Novel?

1 Ответ

0 голосов
/ 26 апреля 2020

Может быть, это глупо, но не должно bookTypeMapperStrategy быть typeof BookMapperStrategy<Novel>, поскольку вы пытаетесь добавить в него что-то типа BookMapperStrategy<Novel>?

...