Проблемы с Typescript, React и Recompose

Заранее извиняюсь за расплывчатое название, мне довольно сложно объяснить мою проблему.

Я пытаюсь использовать React, Recompose и Typescript вместе, но при попытке передать реквизиты в свой компонент я получаю следующую ошибку:

[ts] Property 'bar' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<{}>'.

Компонент импортируется так:

import TestComponent from './TestComponent'

и назвал так:

<TestComponent bar = "hello"/>

Вот структура моей папки компонентов:

├── TestComponent.tsx
├── TestComponentContainer.ts
└── index.ts

index.ts выглядит следующим образом:

import TestComponentContainer from './TestComponentContainer'

export default TestComponentContainer

TestComponent.jsx выглядит следующим образом:

import * as React from 'react'

interface IProps {
  foo: string
  bar: string
}

const TestComponent: React.SFC<IProps> = ({ foo, bar }) => (
  <div>
    <p>{foo}</p>
    <p>{bar}</p>
  </div>
)

export default TestComponent

TestComponentContainer.ts выглядит следующим образом:

import { compose, withProps } from 'recompose'

import TestComponent from './TestComponent'

export default compose(
  withProps({
    foo: 'stringy string string',
  }),
)(TestComponent)

Я понимаю, что мне не хватает какого-то объявления типа для пропсов, которые проходят, но я не могу, хоть убей, точно определить, что мне делать.

Редактировать:

Кроме того, как это сделать при вложенном подходе:

export default compose(
  setDisplayName('PlayerCardContainer'),
  withMutation(mutation),
  withHandlers(createHandlers),
)(PlayerCard)
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
1 687
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

набор текста для сочинения очень общий и позволяет вам указать тип результирующего компонента и тип компонента, который он может быть вызван в но это не гарантирует безопасность типа или совместимость переданных ему функций.

По этой причине лучше избегать compose и просто вкладывать вызовы HOC:

import { withProps } from 'recompose';

import TestComponent from './TestComponent';

export default withProps({
  foo: 'stringy string string',
})(TestComponent);

Редактировать:

Для добавленного примера кода вложение HOC вместо использования compose будет выглядеть следующим образом:

export default setDisplayName('PlayerCardContainer')(
  withMutation(mutation)(
    withHandlers(createHandlers)(
      PlayerCard
    )
  )
);

хорошее строковое значение, кстати ?

Brian Adams 17.09.2018 20:03

Ха-ха, спасибо на обоих аккаунтах, похоже, это сработало! Я полагаю, что я теряю аспект компоновки при перекомпоновке, хотя, делая это, не так ли? Что, если я захочу использовать там еще один HOC, например withHandlers?

bert 17.09.2018 20:17

Извините, что я правильно прочитал вам вторую ссылку, так как она там очень хорошо объяснена! Спасибо за вашу помощь

bert 17.09.2018 20:36

Еще раз извинения! Я не понимаю, как можно использовать вложенный метод, когда каждый HOC принимает собственные аргументы. Я изменил свой вопрос, чтобы вы могли видеть отформатированный код того, что я имею в виду.

bert 17.09.2018 21:02

не беспокойтесь, важно помнить, что все setDisplayName('PlayerCardContainer'), withMutation(mutation) и withHandlers(createHandlers) возвращают функции. compose - это просто синтаксический сахар для вызова каждого в результате вызова следующего. Он превращает вызовы вложенных функций в красивый плоский список, но это все, что он делает. Если типизация улучшится, было бы неплохо сохранить синтаксический сахар, но до тех пор, пока типизация не улучшится, безопаснее вкладывать функции, чтобы TypeScript точно знал, что происходит, и мог эффективно применять статическую типизацию.

Brian Adams 17.09.2018 21:52

Ага, это просто правильно щелкнули для меня, большое спасибо!

bert 17.09.2018 21:53

Как ни странно, это работает абсолютно нормально, когда у меня есть только withMutation и withHandlers, но как только я пытаюсь вложить их в setDisplayName, он снова ломается с Property 'bar' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<{}>'.

bert 17.09.2018 21:59

Хм. Файл при вводе для setDisplayName используется аргумент типа. Я мог бы открыть запрос на перенос, чтобы изменить это, нет причин, по которым setDisplayName не может определить тип. А пока вы можете передать {bar: string} в качестве аргумента типа следующим образом: setDisplayName<{bar: string}>(...

Brian Adams 18.09.2018 00:20

обновление: PR просто слился, чтобы вы могли удалить аргумент типа для setDisplayName с версией 0.27.0 или выше @ types / Recompose

Brian Adams 04.10.2018 05:05

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