Как перевести функцию маршрутизатора React в Typescript?

#javascript #reactjs #typescript #react-router-dom

#javascript #reactjs #typescript #react-router-dom

Вопрос:

Я начинаю работу над проектом React, использующим react-router-dom, и клиенту необходимо преобразовать код проекта в Typescript

Я создаю 2 папки «RouteWrapper.js » и «ProviderRoutes.js «

1- «RouteWrapper.js «

 import React from 'react';
import PropTypes from 'prop-types';
import { Route, Redirect } from 'react-router-dom';

export default function RouteWrapper({
  component: Component,
  isPrivate,
  ...rest
}) {
  const signed = false;

  if (!signed amp;amp; isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed amp;amp; !isPrivate) {
    return <Redirect to="/" />;
  }

  return (
    <Route {...rest} component={Component} />
  );
}

RouteWrapper.propTypes = {
  isPrivate: PropTypes.bool,
  component: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
    .isRequired,
};

RouteWrapper.defaultProps = {
  isPrivate: false,
};
  

2- «ProviderRoutes.js «

 import React from 'react';
import { Switch } from 'react-router-dom';

// Components
import Route from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes() {
  return (
    <Switch>
        <Route exact path={["/signin", "/signup", "/reset-password"]} component={Authentication} />
        <Route path="/" component={ChatApplication} isPrivate />
    </Switch>
  )
}
  

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

1. Typescript — это надмножество JavaScript. Итак, это уже typescript. С какой проблемой вы столкнулись?

2. В первой строке файла 6 и 7 «Элемент привязки’Component’ неявно имеет тип ‘any’.» и «Элемент привязки’isPrivate’ неявно имеет тип’any'».

3. Вы собираетесь спросить нас, как добавлять типы для каждой строки этого кода?

4. Да, пожалуйста, извините, я запутался в проблеме

5. Это слишком широко для stackoverflow (мы могли бы написать об этом серию блогов)

Ответ №1:

Я считаю, что проблема в основном в RouteWrapper . Во-первых, давайте предположим, что вы больше не захотите использовать prop-типы, поскольку типы теперь проверяются TypeScript во время компиляции.

Это основы:

  • React экспортируется с помощью module.exports = React . Это означает, что технически правильный способ импортировать React — это import * as React from 'react'; . В качестве альтернативы вы можете установить "esModuleInterop": true tsconfig.json .
  • Возвращаемый тип компонентов React — React.ReactElement .

Также можно использовать деструктурирование для назначения простых реквизитов по умолчанию в функциональных компонентах.

For <RouteWrapper /> specifically component извлекается из реквизита, а затем передается <Route /> вместе с другими реквизитами. Это означает, что он также может быть включен в rest props.

Поскольку остальные реквизиты передаются в <Route /> , тип реквизитов для <RouteWrapper /> должен расширяться RouteProps от react-router-dom .

RouteWrapper будет выглядеть так:

 import * as React from 'react';
import { Redirect, Route, RouteProps } from 'react-router-dom';

interface RouteWrapperProps extends RouteProps {
  isPrivate: boolean;
}

export default function RouteWrapper({
  isPrivate = false,
  ...rest
}: RouteWrapperProps): ReactElement {
  const signed = false;

  if (!signed amp;amp; isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed amp;amp; !isPrivate) {
    return <Redirect to="/" />;
  }

  return <Route {...rest} />;
}
  

Если вы действительно хотите использовать propTypes или defaultProps , безопасность типов можно добавить с помощью React.FC .

 import * as PropTypes from 'prop-types';
import * as React from 'react';
import { Redirect, Route, RouteProps } from 'react-router-dom';

interface RouteWrapperProps extends RouteProps {
  isPrivate: boolean;
}

const RouteWrapper: React.FC<RouteWrapperProps> = ({ isPrivate, ...rest }) => {
  const signed = false;

  if (!signed amp;amp; isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed amp;amp; !isPrivate) {
    return <Redirect to="/" />;
  }

  return <Route {...rest} />;
};

RouteWrapper.propTypes = {
  isPrivate: PropTypes.bool,
};

RouteWrapper.defaultProps = {
  isPrivate: false,
};

export default RouteWrapper;
  

Остерегайтесь предпочтительного способа написания маршрутов react-router с использованием дочерних элементов, а не
component реквизита.

 import * as React from 'react';
import { Switch } from 'react-router-dom';

// Components
import RouteWrapper from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes(): React.ReactElement {
  return (
    <Switch>
      <Route exact path={['/signin', '/signup', '/reset-password']}>
        <Authentication />
      </Route>
      <Route isPrivate path="/">
        <ChatApplication />
      </Route>
    </Switch>
  );
}
  

Это должно помочь вам начать преобразование остальной части приложения. 🙂

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

1. Сначала я хочу поблагодарить вас за ваш ответ, я пытаюсь с помощью вашего кода поместить, что я нашел эту проблему «Type ‘{ isPrivate: PropTypes. Требуемое значение <логическое значение>; }’ не может быть присвоено типу ‘WeakValidationMap<RouteWrapperProps>’.»