Definitelytyped: @types/react Сделать возможным рендеринг строки из функционального компонента

Созданный на 13 окт. 2017  ·  19Комментарии  ·  Источник: DefinitelyTyped/DefinitelyTyped

  • [x] Я пытался использовать пакет @types/react , и у меня возникли проблемы.
  • [x] Я пытался использовать последнюю стабильную версию tsc. https://www.npmjs.com/package/typescript
  • [x] У меня есть вопрос, который не подходит для StackOverflow . (Пожалуйста, задавайте любые соответствующие вопросы там).
  • [x] [Упомяните] (https://github.com/blog/821-mention-somebody-they-re-notified) авторов (см. Definitions by: в index.d.ts ), чтобы они могли отвечать.

    • Авторы: @johnnyreilly , @bbenezech , ...

С текущими типизациями невозможно создать компонент без состояния, который возвращает строку, число, логическое значение... (новое в React 16)

import React from 'react'

const TestString = () => {
    return 'Test String Component'
}

const Component = () => (
    <div>
        <TestString/>
    </div>
)

Ошибка, которую я получаю:

JSX element type 'string' is not a constructor function for JSX elements.

Первая проблема заключается в том, что в настоящее время в типизациях компонент без состояния не может возвращать ничего, кроме экземпляра React.Element . Это должно быть изменено на (я думаю, я основывал его на изменениях в методе render , см. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index. д.ц#L422)

interface StatelessComponent<P = {}> {
        (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | Array<ReactElement<any>> | string | number | null;
        propTypes?: ValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
}

Вторая проблема заключается в том, что за кулисами компилятор преобразует jsx в `React.createElement('Компонент тестовой строки', null)``

Я получаю сообщение об ошибке компилятора о том, что это недопустимое значение. Кажется, это должно быть одно из значений, указанных в следующем списке: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L3465.

Любые мысли о том, как это можно исправить?

Самый полезный комментарий

Есть новости по этому вопросу?

Все 19 Комментарий

@DovydasNavickas @sandersn @tkrotoff @andy-ms @ddwwcruz @apexskier @devrelm @RyanCavanaugh @richseviora @onigoetz @minestarks @yuit @sboehler @plantain-00 @p- jackson @miracle2k @voxmatt @morcerf @janechu @gaspard @vbfox @ericanderson @dyst5422 @rapilabs @cynecx @newyankeecodeshop

Вероятно, теперь мы могли бы определить компоненты без сохранения состояния и на основе классов как возвращающие ReactNode . Да, я не перешел на v16, так что это требует тестирования.

Похоже, PR уже открыт. https://github.com/DefinitelyTyped/DefinitelyTyped/pull/20097

Это работает на банкомате?

Я пытался изменить его, но он ломает синтаксический анализатор JSX, если возвращаемый тип string boolean или undefined .

Об этом идет PR TypeScript: https://github.com/Microsoft/TypeScript/pull/20239 (ну, это о массивах, но, как правило, TS должен знать, что разрешено в компоненте JSX)

Круто, спасибо за обновление!

Что нового по этому поводу? Я вижу, что упомянутый выше TS PR (https://github.com/Microsoft/TypeScript/pull/20239) теперь закрыт/заблокирован. Сегодня я столкнулся с тем же самым, новичок в машинописном тексте + реакция, и мне интересно, почему мои компоненты не могут внезапно возвращать строки...

Обходной путь — вернуть фрагмент.

return <>0</>

Есть новости по этому вопросу?

Привет, какие-либо обновления или намеки на это, пожалуйста :)?

По сути, это дубликат # 18912. После разрешения Microsoft/TypeScript#21699 мы сможем использовать ReactNode в качестве допустимого типа возвращаемого значения для функциональных компонентов, которые включают string и boolean .

Чтобы обобщить проблему, почему он вообще должен предполагать, что законно для React? С прагмами @jsx / @jsxFrag Babel подход, подобный этому JSX, может работать с любыми функциями. Так что дело даже не в том, что следует допускать только строки; любое возвращаемое значение может быть законным, ограниченным только конкретным использованием. React важен, но это просто конкретная библиотека рендеринга.

Это было открыто в течение почти пары лет, есть ли какое-либо решение?

О предлагаемом возврате фрагмента <> StringValue идет сюда> - я думаю, у меня проблемы с пониманием того, как я получаю строковое значение или любой другой тип значения, который не является React.Element действительно для использования в моем коде - например, если У меня есть функция Howdy, возвращающая <>"hello">, а внутри componentDidMount у меня есть

константа что говорит =

как мне получить строковое значение из фрагмента. Я не вижу способа, кажется, что любой способ обойти это - чрезвычайно уродливый хак, и учитывая, что API-интерфейс Hooks часто используется с возвратом только строк или других значений элемента, отличных от React, например https://github. com/pankod/react-hooks-screen-type/blob/master/src/index.js
мне кажется, что эта ошибка действительно делает API-интерфейс Hooks непригодным для использования и, таким образом, делает Typescript плохо подходящим для React.

Это было открыто в течение почти пары лет, есть ли какое-либо решение?

@bryanrasmussen См. https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544#issuecomment -459665668 для последнего обновления.

Эта проблема заставляет нас писать типичный код React, чтобы обойти ограничения, налагаемые TypeScript. Единственный способ устранить эти ошибки с помощью TypeScript — добавить дополнительные элементы DOM и/или React.Fragments, которые добавляют накладные расходы (генерируют мусор), и они не нужны.

Это не всегда проблема, поскольку она возникает время от времени и срабатывает, когда вы возвращаете допустимые вещи из компонентов React, которые не совсем JSX.Element, например, массив.

Я был бы счастлив с разумной аннотацией типа, чтобы помочь делу, но я должен раздавить их несовершенными вещами, такими как дополнительные слои и/или any . Фигово.

Обертка с ненужным React.Fragment имеет (незначительную) стоимость во время выполнения.

Может ли это быть еще одним обходным путем без штрафа за время выполнения?

import React, { ReactElement } from 'react'

const TestString = () => {
  return ('Test String Component' as unknown) as ReactElement
}

const Component = () => (
  <div>
    <TestString />
  </div>
)

export default Component

Обертка с ненужным React.Fragment имеет (незначительную) стоимость во время выполнения.

Это компромисс. Тем не менее, хотелось бы видеть лучшую типизацию для этого. Кроме того, немаловажно, зависит от контекста. Несколько осколков не повредят, их будет много.

Обертка с ненужным React.Fragment имеет (незначительную) стоимость во время выполнения.

Может ли это быть еще одним обходным путем без штрафа за время выполнения?

import React, { ReactElement } from 'react'

const TestString = () => {
  return ('Test String Component' as unknown) as ReactElement
}

const Component = () => (
  <div>
    <TestString />
  </div>
)

export default Component

Да, но тогда я также теряю проверку типов для функции. Я имею в виду, что я также могу удалить TS из своего проекта без каких-либо штрафов во время выполнения, но тогда у меня нет проверки типов. Таким образом, ваш обходной путь, безусловно, работает, но просто нарушает цель TS. Кастинг на «то, что вы ожидаете» — это все равно, что сказать: «Хорошо, тогда давайте отбросим перерывы. Кому это вообще нужно?». Когда вы заключаете его во фрагмент, вы получаете правильную проверку типов!

Итак, есть новости по исправлению?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги