fix(client): refactor to use correct i18n t type (#42865)

* fix(client): refactor to use correct i18n t type

* appease Oliver by importing directly from react-i18n

* fix: use default TFunction type variable

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Shaun Hamilton
2021-07-19 17:48:02 +01:00
committed by GitHub
parent 25f145b5c8
commit 31486b368b
23 changed files with 43 additions and 43 deletions

View File

@ -11,7 +11,7 @@ import {
Row Row
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { Trans, withTranslation } from 'react-i18next'; import { TFunction, Trans, withTranslation } from 'react-i18next';
import Login from '../components/Header/components/Login'; import Login from '../components/Header/components/Login';
@ -30,7 +30,7 @@ interface IShowUserProps {
username: string; username: string;
reportDescription: string; reportDescription: string;
}) => void; }) => void;
t: (payload: unknown, ops?: Record<string, unknown>) => string; t: TFunction;
userFetchState: { userFetchState: {
pending: boolean; pending: boolean;
complete: boolean; complete: boolean;

View File

@ -10,7 +10,7 @@
// @ts-nocheck // @ts-nocheck
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { import {
faCheck, faCheck,
@ -38,7 +38,7 @@ export interface NavLinksProps {
displayMenu?: boolean; displayMenu?: boolean;
fetchState?: { pending: boolean }; fetchState?: { pending: boolean };
i18n: Object; i18n: Object;
t: (x: any) => any; t: TFunction;
toggleDisplayMenu?: React.MouseEventHandler<HTMLButtonElement>; toggleDisplayMenu?: React.MouseEventHandler<HTMLButtonElement>;
toggleNightMode: (x: any) => any; toggleNightMode: (x: any) => any;
user?: Record<string, unknown>; user?: Record<string, unknown>;

View File

@ -55,7 +55,7 @@ interface IProfileProps {
function renderMessage( function renderMessage(
isSessionUser: boolean, isSessionUser: boolean,
username: string, username: string,
t: TFunction<'translation'> t: TFunction
): JSX.Element { ): JSX.Element {
return isSessionUser ? ( return isSessionUser ? (
<> <>

View File

@ -43,7 +43,7 @@ interface ICamperProps {
yearsTopContributor: string[]; yearsTopContributor: string[];
} }
function joinArray(array: string[], t: TFunction<'translation'>): string { function joinArray(array: string[], t: TFunction): string {
return array.reduce((string, item, index, array) => { return array.reduce((string, item, index, array) => {
if (string.length > 0) { if (string.length > 0) {
if (index === array.length - 1) { if (index === array.length - 1) {
@ -57,7 +57,7 @@ function joinArray(array: string[], t: TFunction<'translation'>): string {
}); });
} }
function parseDate(joinDate: string, t: TFunction<'translation'>): string { function parseDate(joinDate: string, t: TFunction): string {
const convertedJoinDate = new Date(joinDate); const convertedJoinDate = new Date(joinDate);
const date = convertedJoinDate.toLocaleString([localeCode, 'en-US'], { const date = convertedJoinDate.toLocaleString([localeCode, 'en-US'], {
year: 'numeric', year: 'numeric',

View File

@ -50,7 +50,7 @@ interface IHeatMapInnerProps {
longestStreak: number; longestStreak: number;
pages: IPageData[]; pages: IPageData[];
points?: number; points?: number;
t: TFunction<'translation'>; t: TFunction;
} }
interface IHeatMapInnerState { interface IHeatMapInnerState {

View File

@ -64,7 +64,7 @@ interface ICompletedMap {
interface ITimelineProps { interface ITimelineProps {
completedMap: ICompletedMap[]; completedMap: ICompletedMap[];
t: TFunction<'translation'>; t: TFunction;
username: string; username: string;
} }

View File

@ -13,7 +13,7 @@ import { FullWidthRow, Spacer } from '../helpers';
import ThemeSettings from './theme'; import ThemeSettings from './theme';
import UsernameSettings from './username'; import UsernameSettings from './username';
import BlockSaveButton from '../helpers/form/block-save-button'; import BlockSaveButton from '../helpers/form/block-save-button';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
type FormValues = { type FormValues = {
name: string; name: string;
@ -30,7 +30,7 @@ type AboutProps = {
picture: string; picture: string;
points: number; points: number;
submitNewAbout: (formValues: FormValues) => void; submitNewAbout: (formValues: FormValues) => void;
t: (str: string) => string; t: TFunction;
toggleNightMode: (theme: string) => void; toggleNightMode: (theme: string) => void;
username: string; username: string;
}; };

View File

@ -4,7 +4,7 @@ import React, { Component } from 'react';
import { Button, Panel } from '@freecodecamp/react-bootstrap'; import { Button, Panel } from '@freecodecamp/react-bootstrap';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { FullWidthRow, ButtonSpacer, Spacer } from '../helpers'; import { FullWidthRow, ButtonSpacer, Spacer } from '../helpers';
@ -17,7 +17,7 @@ import './danger-zone.css';
type DangerZoneProps = { type DangerZoneProps = {
deleteAccount: () => void; deleteAccount: () => void;
resetProgress: () => void; resetProgress: () => void;
t: (str: string) => JSX.Element; t: TFunction;
}; };
type DangerZoneState = { type DangerZoneState = {

View File

@ -13,7 +13,7 @@ import {
// @ts-ignore // @ts-ignore
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import isEmail from 'validator/lib/isEmail'; import isEmail from 'validator/lib/isEmail';
import { Trans, withTranslation } from 'react-i18next'; import { TFunction, Trans, withTranslation } from 'react-i18next';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { updateMyEmail } from '../../redux/settings'; import { updateMyEmail } from '../../redux/settings';
@ -33,7 +33,7 @@ type EmailProps = {
email: string; email: string;
isEmailVerified: boolean; isEmailVerified: boolean;
sendQuincyEmail: boolean; sendQuincyEmail: boolean;
t: (str: string) => string; t: TFunction;
updateMyEmail: (email: string) => void; updateMyEmail: (email: string) => void;
updateQuincyEmail: (sendQuincyEmail: boolean) => void; updateQuincyEmail: (sendQuincyEmail: boolean) => void;
}; };

View File

@ -10,7 +10,7 @@ import {
// @ts-ignore // @ts-ignore
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import isURL from 'validator/lib/isURL'; import isURL from 'validator/lib/isURL';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { maybeUrlRE } from '../../utils'; import { maybeUrlRE } from '../../utils';
@ -26,7 +26,7 @@ interface InternetFormValues {
} }
interface InternetProps extends InternetFormValues { interface InternetProps extends InternetFormValues {
t: (str: string) => string; t: TFunction;
updateInternetSettings: (formValues: InternetFormValues) => void; updateInternetSettings: (formValues: InternetFormValues) => void;
} }

View File

@ -11,7 +11,7 @@ import {
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import { findIndex, find, isEqual } from 'lodash-es'; import { findIndex, find, isEqual } from 'lodash-es';
import isURL from 'validator/lib/isURL'; import isURL from 'validator/lib/isURL';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { hasProtocolRE } from '../../utils'; import { hasProtocolRE } from '../../utils';
@ -30,7 +30,7 @@ type PortfolioValues = {
type PortfolioProps = { type PortfolioProps = {
picture?: string; picture?: string;
portfolio: PortfolioValues[]; portfolio: PortfolioValues[];
t: (str: string, obj?: { charsLeft: number }) => string; t: TFunction;
updatePortfolio: (obj: { portfolio: PortfolioValues[] }) => void; updatePortfolio: (obj: { portfolio: PortfolioValues[] }) => void;
username?: string; username?: string;
}; };

View File

@ -5,7 +5,7 @@ import { createSelector } from 'reselect';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
import { Button, Form } from '@freecodecamp/react-bootstrap'; import { Button, Form } from '@freecodecamp/react-bootstrap';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { userSelector } from '../../redux'; import { userSelector } from '../../redux';
@ -39,7 +39,7 @@ type ProfileUIType = {
type PrivacyProps = { type PrivacyProps = {
submitProfileUI: (profileUI: ProfileUIType) => void; submitProfileUI: (profileUI: ProfileUIType) => void;
t: (str: string) => string; t: TFunction;
user: { user: {
profileUI: ProfileUIType; profileUI: ProfileUIType;
username: string; username: string;

View File

@ -11,7 +11,7 @@ import {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { import {
@ -26,7 +26,7 @@ import { isValidUsername } from '../../../../utils/validate';
type UsernameProps = { type UsernameProps = {
isValidUsername: boolean; isValidUsername: boolean;
submitNewUsername: (name: string) => void; submitNewUsername: (name: string) => void;
t: (str: string, obj?: { username: string }) => string; t: TFunction;
username: string; username: string;
validateUsername: (name: string) => void; validateUsername: (name: string) => void;
validating: boolean; validating: boolean;

View File

@ -5,7 +5,7 @@ import type { Dispatch } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { Grid, Row, Col, Alert } from '@freecodecamp/react-bootstrap'; import { Grid, Row, Col, Alert } from '@freecodecamp/react-bootstrap';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { Spacer, Loader } from '../components/helpers'; import { Spacer, Loader } from '../components/helpers';
import DonateForm from '../components/Donation/DonateForm'; import DonateForm from '../components/Donation/DonateForm';
@ -32,7 +32,7 @@ interface DonatePageProps {
executeGA: (arg: ExecuteGaArg) => void; executeGA: (arg: ExecuteGaArg) => void;
isDonating?: boolean; isDonating?: boolean;
showLoading: boolean; showLoading: boolean;
t: (s: string) => string; t: TFunction;
} }
const mapStateToProps = createSelector( const mapStateToProps = createSelector(

View File

@ -4,7 +4,7 @@ import type { Dispatch } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import SectionHeader from '../components/settings/section-header'; import SectionHeader from '../components/settings/section-header';
import IntroDescription from '../components/Intro/components/IntroDescription'; import IntroDescription from '../components/Intro/components/IntroDescription';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { Row, Col, Button, Grid } from '@freecodecamp/react-bootstrap'; import { Row, Col, Button, Grid } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
@ -19,7 +19,7 @@ import './email-sign-up.css';
interface AcceptPrivacyTermsProps { interface AcceptPrivacyTermsProps {
acceptTerms: (accept: boolean | null) => void; acceptTerms: (accept: boolean | null) => void;
acceptedPrivacyTerms: boolean; acceptedPrivacyTerms: boolean;
t: (s: string) => string; t: TFunction;
} }
const mapStateToProps = createSelector( const mapStateToProps = createSelector(

View File

@ -18,7 +18,7 @@ import {
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import isEmail from 'validator/lib/isEmail'; import isEmail from 'validator/lib/isEmail';
import { isString } from 'lodash-es'; import { isString } from 'lodash-es';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { Spacer } from '../components/helpers'; import { Spacer } from '../components/helpers';
import './update-email.css'; import './update-email.css';
@ -28,7 +28,7 @@ import { maybeEmailRE } from '../utils';
interface UpdateEmailProps { interface UpdateEmailProps {
isNewEmail: boolean; isNewEmail: boolean;
t: (s: string) => string; t: TFunction;
updateMyEmail: (e: string) => void; updateMyEmail: (e: string) => void;
} }

View File

@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { graphql } from 'gatsby'; import { graphql } from 'gatsby';
import Media from 'react-responsive'; import Media from 'react-responsive';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
// Local Utilities // Local Utilities
import LearnLayout from '../../../components/layouts/learn'; import LearnLayout from '../../../components/layouts/learn';
@ -87,7 +87,7 @@ interface ShowClassicProps {
pageContext: { pageContext: {
challengeMeta: ChallengeMetaType; challengeMeta: ChallengeMetaType;
}; };
t: (arg0: string) => string; t: TFunction;
tests: TestType[]; tests: TestType[];
updateChallengeMeta: (arg0: ChallengeMetaType) => void; updateChallengeMeta: (arg0: ChallengeMetaType) => void;
} }

View File

@ -1,13 +1,13 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import BezierEasing from 'bezier-easing'; import BezierEasing from 'bezier-easing';
import GreenPass from '../../../assets/icons/green-pass'; import GreenPass from '../../../assets/icons/green-pass';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
interface CompletionModalBodyProps { interface CompletionModalBodyProps {
block: string; block: string;
completedPercent: number; completedPercent: number;
superBlock: string; superBlock: string;
t: (arg0: string, arg1?: { percent: number }) => string; t: TFunction;
} }
interface CompletionModalBodyState { interface CompletionModalBodyState {

View File

@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { Button, Modal } from '@freecodecamp/react-bootstrap'; import { Button, Modal } from '@freecodecamp/react-bootstrap';
import { useStaticQuery, graphql } from 'gatsby'; import { useStaticQuery, graphql } from 'gatsby';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import Login from '../../../components/Header/components/Login'; import Login from '../../../components/Header/components/Login';
@ -106,7 +106,7 @@ interface CompletionModalsProps {
message: string; message: string;
submitChallenge: () => void; submitChallenge: () => void;
superBlock: string; superBlock: string;
t: (arg0: string) => string; t: TFunction;
title: string; title: string;
} }

View File

@ -8,7 +8,7 @@ import { createSelector } from 'reselect';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { graphql } from 'gatsby'; import { graphql } from 'gatsby';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
// Local Utilities // Local Utilities
import { import {
@ -88,7 +88,7 @@ interface BackEndProps {
pageContext: { pageContext: {
challengeMeta: ChallengeMetaType; challengeMeta: ChallengeMetaType;
}; };
t: (arg0: string) => string; t: TFunction;
tests: TestType[]; tests: TestType[];
title: string; title: string;
updateChallengeMeta: (arg0: ChallengeMetaType) => void; updateChallengeMeta: (arg0: ChallengeMetaType) => void;

View File

@ -7,7 +7,7 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { graphql } from 'gatsby'; import { graphql } from 'gatsby';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
@ -62,7 +62,7 @@ interface ProjectProps {
pageContext: { pageContext: {
challengeMeta: ChallengeMetaType; challengeMeta: ChallengeMetaType;
}; };
t: (arg0: string) => string; t: TFunction;
updateChallengeMeta: (arg0: ChallengeMetaType) => void; updateChallengeMeta: (arg0: ChallengeMetaType) => void;
updateSolutionFormValues: () => void; updateSolutionFormValues: () => void;
} }

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button } from '@freecodecamp/react-bootstrap'; import { Button } from '@freecodecamp/react-bootstrap';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import { openModal } from '../redux'; import { openModal } from '../redux';
@ -21,7 +21,7 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
interface ToolPanelProps { interface ToolPanelProps {
guideUrl?: string; guideUrl?: string;
openHelpModal: () => void; openHelpModal: () => void;
t: (args: string) => void; t: TFunction;
} }
export class ToolPanel extends Component<ToolPanelProps> { export class ToolPanel extends Component<ToolPanelProps> {

View File

@ -8,7 +8,7 @@ import Helmet from 'react-helmet';
import YouTube from 'react-youtube'; import YouTube from 'react-youtube';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { ObserveKeys } from 'react-hotkeys'; import { ObserveKeys } from 'react-hotkeys';
import { withTranslation } from 'react-i18next'; import { TFunction, withTranslation } from 'react-i18next';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
// Local Utilities // Local Utilities
@ -63,7 +63,7 @@ interface ShowVideoProps {
pageContext: { pageContext: {
challengeMeta: ChallengeMetaType; challengeMeta: ChallengeMetaType;
}; };
t: (arg0: string) => string; t: TFunction;
updateChallengeMeta: (arg0: ChallengeMetaType) => void; updateChallengeMeta: (arg0: ChallengeMetaType) => void;
updateSolutionFormValues: () => void; updateSolutionFormValues: () => void;
} }