Использование реакции v18 с Typescript <v5.1, при этом разрешая строку как допустимый элемент JSX

Полный воспроизводимый репозиторий — https://github.com/Liooo/vite-project, просто запустите yarn install && yarn tsc, чтобы увидеть ошибку.

Я хочу использовать реакцию v18 с Typescript <v5.1, но tsc выдает ошибку TS2786 'MyComponent' cannot be used as a JSX component. Its return type 'string' is not a valid JSX element., как показано ниже:

const MyComponent = () => 'x'

function App() {
  return (
    <>
      <div>
        <MyComponent />
       // ↑
        // error TS2786: 'MyComponent' cannot be used as a JSX component.
        //     Its return type 'string' is not a valid JSX element.
      </div>
    </>
  )
}
// package.json
{

  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "typescript": "4.9.5" // <= the error disappears with for example "5.1.6"
  }
}

Когда я обновляю машинописный текст до > v5.1, ошибка исчезает.

Пробовал настроить расширение JSX.Element вот так, но пока безуспешно.

если быть точным, то моя цель здесь следующая:

  1. используйте реакцию@v18
  2. используйте машинопись@v4.9.5
  3. разрешить строку (и другие типы ReactNode) как действительный элемент JSX

Примечания:

Обертывание строк в такие элементы, как const MyComponent = () => (<>{'x'}</>), работает, но я не хочу этого делать, хочу иметь возможность возвращать строку из компонента)

Ошибка должна быть связана с этой проблемой с Microsoft/Typescript

Пробовали ли вы вместо этого вернуть фрагмент JSX? return <>some string</>;

Phil 27.06.2024 03:55

Причина, по которой это работает в версии 5.1+, вероятно, связана с несвязанной проверкой типов между элементами JSX и типами тегов JSX в ответ на эту проблему

Phil 27.06.2024 04:02

Отвечает ли это на ваш вопрос? Как вернуть строку или элемент JSX в компоненте TypeScript React?

Phil 27.06.2024 04:04

@Фил, да, это работает, но так не должно быть.

Ryo 27.06.2024 04:08

Я не понимаю, о чем вы спрашиваете. Да, это была проблема в TypeScript. Да, они это исправили. Как и в случае с любой ошибкой в ​​старом программном обеспечении, если вы не можете обновиться, вам нужен обходной путь.

Phil 27.06.2024 04:09

@Phil наша старая кодовая база сильно ломается при обновлении машинописного текста, требование состоит в том, чтобы использовать реакцию v18, Typescript < v5.1 и разрешать строку (а также число и другие типы в стиле ReactNode) быть действительными как JSX.Element. Я думал, что расширение модуля — это обходной путь, но мне с этим не повезло.

Ryo 27.06.2024 04:14

И я думаю, что причина ошибки как раз связана с этой github.com/microsoft/TypeScript/pull/51328

Ryo 27.06.2024 04:15

«Я ищу обходной путь»… некоторые из них вам были представлены в предложенном дубликате . Вы пробовали это? Если да, то почему они не удовлетворяют вашим требованиям?

Phil 27.06.2024 04:22

@Phil Ни один из этих вариантов не является тем обходным путем, который я ищу, они предлагают обертывать компонент, а не

Ryo 27.06.2024 04:28

Решение состоит в том, чтобы не использовать такое на старой версии TS, насколько сложно его обновить? Обычно это легко

nanobar 27.06.2024 04:29

Вы пробовали return "mystring" as unknown as JSX.Element согласно этому ответу? Вы также не объяснили, почему вы не можете обернуть строку во фрагмент.

Phil 27.06.2024 04:29

по сути это то же самое, что заключить <>{...}</>. как я уже сказал, я хочу, чтобы JSX.Element принимал строки и другие типы ReactNode в базе кода, как и должно быть.

Ryo 27.06.2024 04:31

Это просто невозможно с той версией TypeScript, которую вы используете, и нет, это даже близко не одно и то же. Совершенно неясно, какой ответ вы здесь ищете, но это похоже на простое принятие желаемого за действительное... «Я хочу, чтобы эта конкретная версия TypeScript делала то, что она не может делать без моих изменений»

Phil 27.06.2024 04:32

@Доминик, мы бы сделали это, если бы могли, но у нас есть куча устаревшей кодовой базы, которая резко ломается после обновления ts, и мы решили не делать этого прямо сейчас, поэтому ищем обходной путь :(

Ryo 27.06.2024 04:34

@Фил, как я уже сказал, тип обходного пути, который я ищу, другой, я предположил, что расширение модуля может быть таким же способом, как и то, что сделал TypeScript на github.com/microsoft/TypeScript/pull/51328

Ryo 27.06.2024 04:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
16
115
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

просто запустить функцию? Зачем пытаться заставить функциональный компонент возвращать строку?

const myStringfunc = (): string => { return 'x' }
...
<div>{ myStringfunc() }</div>

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

в этом примере это не компонент, а статическая функция, я просто сохранил используемое соглашение об именах.

danielRICADO 27.06.2024 06:08

спасибо, но я хочу разрешить отображение строки как элемента JSX по всей базе кода. Причина в том, что это исходное поведение реакции, и мы хотим, чтобы тип работал соответствующим образом, не заключая все вхождения в return <>{stringVar}</> или return stringVar as unknown as ReactElement и т. д.

Ryo 27.06.2024 07:42

ок, тогда вроде как принял ответ, другого обходного пути, кроме обновления TS, нет.

danielRICADO 30.06.2024 22:27
Ответ принят как подходящий

Нет обходного пути, кроме обновления машинописного текста:

https://github.com/DefiniteTyped/DefinitelyTyped/discussions/69919#discussioncomment-9892117

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