Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frontend: add eslint rule restrict-template-expressions #2325

Merged

Conversation

thisconnect
Copy link
Collaborator

So that we do not accidentally pass undefined, null, booleans or just any type in tempalte literals, see:

`all these should error ${false} ${undefined} ${[]} ${null}`

This is a eslint rule, so only make weblint will check.

@thisconnect thisconnect marked this pull request as draft October 31, 2023 10:49
@thisconnect
Copy link
Collaborator Author

15 problems 🎉

> npm run typescript && eslint --ext .jsx,.js,.ts,.tsx ./src


> [email protected] typescript
> tsc -p tsconfig.json


/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/api/subscribe.ts
  45:33  error  Invalid type "TEvent" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/components/forms/select.tsx
  44:21  error  Invalid type "string | number | readonly string[] | undefined" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/components/icon/logo.tsx
  70:258  error  Invalid type "any" of template literal expression  @typescript-eslint/restrict-template-expressions
  71:261  error  Invalid type "any" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/i18n/i18n.test.tsx
  42:34  error  Invalid type "string | null" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/account/info/buyReceiveCTA.tsx
  48:25  error  Invalid type "string | undefined" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/account/info/info.tsx
  83:57  error  Invalid type "ScriptType | undefined" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/account/send/send.tsx
  372:95  error  Invalid type "string | true" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/device/bitbox01/restore.tsx
  101:57  error  Invalid type "any" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/device/bitbox01/settings/components/mobile-pairing.tsx
  205:58  error  Invalid type "string | boolean" of template literal expression  @typescript-eslint/restrict-template-expressions
  211:60  error  Invalid type "boolean" of template literal expression           @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/device/bitbox01/setup/initialize.tsx
  110:35  error  Invalid type "string | null" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/device/bitbox01/setup/security-information.tsx
  66:96  error  Invalid type "string | null" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/device/bitbox02/passphrase.tsx
  88:42  error  Invalid type "number | undefined" of template literal expression  @typescript-eslint/restrict-template-expressions

/opt/go/src/github.com/digitalbitbox/bitbox-wallet-app/frontends/web/src/routes/settings/components/device-settings/attestation-check-setting.tsx
  47:64  error  Invalid type "boolean" of template literal expression  @typescript-eslint/restrict-template-expressions

✖ 15 problems (15 errors, 0 warnings)

So that we do not accidentally pass undefined, null, booleans or
just any type in tempalte literals, see:

    `all these should error ${false} ${undefined} ${[]} ${null}`

This is a eslint rule, so only make weblint will check.
@thisconnect thisconnect force-pushed the frontend-eslint-templateliterals branch from cd023a2 to f8bccf4 Compare November 28, 2024 16:21
Last commit introduced restrict-template-expressions, with this all
reported problems should be fixed.
There seem to be no major edge cases using numbers in template
literals and allowing them seems reasonable.
In c6ee6e0 the large prop on the SwissMadeOpenSource component
was removed as it did not work since a long time and was for
BitBox01 only, this commit removes the unused CSS.
@thisconnect thisconnect marked this pull request as ready for review December 2, 2024 14:26
Copy link
Collaborator Author

@thisconnect thisconnect left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partly pre-reviewd 😇

showQRCode: boolean;
type State = {
channel: string | null;
status: string | false;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed boolean -> false as it is initialized with false.

export const BitBoxSwissInverted = (props: GenericProps) => <img {...props} draggable={false} src={BitBoxSwissInvertedLogo} alt="BitBox" className={style.logo} />;
export const Shift = (props: GenericProps) => <img {...props} draggable={false} src={ShiftLogo} alt="Shift Crypto" className={style.logo} />;
export const SwissMadeOpenSource = ({ large: boolean, className, ...props }: GenericProps) => <img {...props} draggable={false} src={SwissOpenSourceLight} alt="Swiss Made Open Source" className={`${style.swissOpenSource} ${props.large ? style.large : ''} ${className ? className : ''}`} />;
export const SwissMadeOpenSourceDark = ({ large: boolean, className, ...props }: GenericProps) => <img {...props} draggable={false} src={SwissOpenSourceDark} alt="Swiss Made Open Source" className={`${style.swissOpenSource} ${props.large ? style.large : ''} ${className ? className : ''}`} />;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed large as this didn't work and props.large was always undefined:

({ large, ...props }) => props.large // props.large is always undefined

@@ -56,23 +56,22 @@ import PAXG_GREY from './assets/paxg-white.svg';
import ShiftLogo from './assets/shift-cryptosecurity-logo.svg';
import style from './logo.module.css';

interface GenericProps {
[property: string]: any;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed and replaced by type ImgProps = JSX.IntrinsicElements['img']; as we already do in icons.tsx

navigate(`/account/${code}/receive`);
if (code) {
navigate(`/account/${code}/receive`);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit weird and could be cleaned up by refatoring AddBuyReceiveOnEmptyBalances and BuyReceiveCTA component.

I.e. balanceList is probably not really needed in BuyReceiveCTA and something like a boolean prop.isOnAccount or similar may be enough

alertUser(this.props.t(`backup.restore.error.e${code}`, {
defaultValue: errorMessage,
}));
if (typeof code === 'string') {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some un-typed BitBox01 backups specific api call.

We usually know what type when we use the src/api backend calls, but here we call apiPost directly.

@thisconnect thisconnect changed the title draft: add eslint rule restrict-template-expressions frontend: add eslint rule restrict-template-expressions Dec 2, 2024
Copy link
Collaborator

@shonsirsha shonsirsha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks a lot

@@ -41,7 +41,7 @@ export const Select = ({
<select id={id} {...props}>
{options.map(({ value, text, disabled = false }) => (
<option
key={`${value}`}
key={String(value)}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? I guess best practice, right?

Copy link
Collaborator Author

@thisconnect thisconnect Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without converting to string somehow i.e. String() this will error with:

Type 'string | number | readonly string[] | undefined' is not assignable to type 'Key | null | undefined'.
  Type 'readonly string[]' is not assignable to type 'Key | null | undefined'.ts(2322)
index.d.ts(261, 9): The expected type comes from property 'key' which is declared here on type 'DetailedHTMLProps<OptionHTMLAttributes<HTMLOptionElement>, HTMLOptionElement>'
(property) Attributes.key?: Key | null | undefined

We use the intrinsic element option (prob shouldn't :) ) this has the type value?: string | readonly string[] | number | undefined;

    interface OptionHTMLAttributes<T> extends HTMLAttributes<T> {
        disabled?: boolean | undefined;
        label?: string | undefined;
        selected?: boolean | undefined;
        value?: string | readonly string[] | number | undefined;
    }

@thisconnect thisconnect merged commit 1b67bce into BitBoxSwiss:master Dec 3, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants