Skip to content

Commit

Permalink
[TypeScript] Enforce Interfaces over Types (#583)
Browse files Browse the repository at this point in the history
* Add @typescript-eslint/consistent-type-definitions rule, alphabetize and clean up rules

* Convert types to Interfaces, clear up compiler errors

* Convert other src types, modify MediaQueriesType for throwOnUndefined compatibility

* Remove unneeded type export

* Export component prop interface definitions for consumer usage
  • Loading branch information
michaeljaltamirano authored Feb 11, 2021
1 parent fb3db29 commit 2aea377
Show file tree
Hide file tree
Showing 44 changed files with 111 additions and 134 deletions.
54 changes: 21 additions & 33 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
}
},
"rules": {
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": [
"error",
Expand All @@ -37,14 +36,30 @@
"extendDefaults": true
}
],
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/consistent-indexed-object-style": "error",
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-duplicate-imports": "error",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/no-use-before-define": "error",
"@typescript-eslint/consistent-indexed-object-style": "error",
"arrow-parens": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"import/extensions": [
"error",
{
"jpg": "always",
"png": "always",
"svg": "always"
}
],
"no-console": ["error", { "allow": ["warn", "error"] }],
"no-duplicate-imports": "off",
"no-shadow": "off",
Expand All @@ -68,25 +83,11 @@
}
],
"react/state-in-constructor": "off",
"react/static-property-placement": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"import/extensions": [
"error",
{
"jpg": "always",
"png": "always",
"svg": "always"
}
]
"react/static-property-placement": "off"
},
"overrides": [
{
"files": ["test.{js,ts,tsx}"],
"files": ["test.{ts,tsx}"],
"rules": {
"@typescript-eslint/no-unsafe-call": "off",
"no-undef": "off",
Expand All @@ -98,25 +99,12 @@
}
},
{
"files": ["**/style.{js,ts}"],
"files": ["**/style.ts"],
"rules": {
"@typescript-eslint/restrict-template-expressions": "off",
"indent": "off"
}
},
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/restrict-template-expressions": "off"
}
},
{
"files": ["*.tsx"],
"rules": {
Expand All @@ -131,7 +119,7 @@
}
},
{
"files": ["stories/**/*.{js,ts,tsx}"],
"files": ["stories/**/*.{ts,tsx}"],
"rules": {
"no-alert": "off"
}
Expand Down
4 changes: 2 additions & 2 deletions src/constants/keyboardKeys/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import throwOnUndefinedProperty from '../../utils/throwOnUndefinedProperty';

export type KeyType = {
export interface KeyType {
key: string;
keyCode: number;
};
}

const keyboardKeys = throwOnUndefinedProperty({
escape: {
Expand Down
4 changes: 2 additions & 2 deletions src/constants/mediaQueries/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { throwOnUndefinedProperty } from '../../utils';
import BREAKPOINTS from '../breakpoints';

type MediaQueriesType = {
interface MediaQueriesType extends Record<string, unknown> {
xsUp: string;
smUp: string;
mdUp: string;
lgUp: string;
xlUp: string;
xxlUp: string;
};
}

const mediaQueries = Object.entries(BREAKPOINTS).reduce(
(accumulator, [label, px]) => ({
Expand Down
4 changes: 2 additions & 2 deletions src/constants/themes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ export const COLORS_PROP_TYPES = PropTypes.oneOf([
...Object.values(secondaryTheme.COLORS),
]);

export type ThemeType = {
export interface ThemeType {
__type: 'primary' | 'secondary';
BORDER_RADIUS: BorderRadius;
BOX_SHADOWS: BoxShadows;
COLORS: Colors;
FONTS: Fonts;
TYPOGRAPHY: Typography;
};
}
6 changes: 3 additions & 3 deletions src/shared-components/accordion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useTheme } from 'emotion-theming';

import { ThemeType } from '../../constants';
import { ChevronIcon } from '../../icons';
import Thumbnails from './thumbnails';
import { Thumbnails } from './thumbnails';
import {
AccordionBox,
ArrowWrapper,
Expand All @@ -21,7 +21,7 @@ export type BorderRadiusValues =
| '0.5rem'
| '2rem';

type AccordionProps = {
export interface AccordionProps {
/** Sets the border-radius of Accordion.Container, AccordionBox, and TitleWrapper */
borderRadius?: BorderRadiusValues;
/** node(s) that will render only when expanded */
Expand All @@ -40,7 +40,7 @@ type AccordionProps = {
rightAlignArrow?: boolean;
/** node that will render whether collapsed or expanded */
title: React.ReactNode;
};
}

/**
* A list of items that allows each item's content to be expanded and collapsed by clicking its title bar.
Expand Down
8 changes: 3 additions & 5 deletions src/shared-components/accordion/thumbnails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import {
MultiplesText,
} from './style';

type ThumbnailsProps = {
export interface ThumbnailsProps {
/** An array of image src strings that Accordion.Thumbails will use to render */
photoSrcs: Array<string>;
};
}

const Thumbnails = ({ photoSrcs }: ThumbnailsProps) => {
export const Thumbnails = ({ photoSrcs }: ThumbnailsProps) => {
/**
* Thumbnail images set with empty alt text because they are decorative.
* Accessible Accordion functionality does not depend on these thumbnails.
Expand Down Expand Up @@ -55,5 +55,3 @@ const Thumbnails = ({ photoSrcs }: ThumbnailsProps) => {

return <Container>{renderThumbnails()}</Container>;
};

export default Thumbnails;
4 changes: 2 additions & 2 deletions src/shared-components/alert/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const alertIconMapping = {

export type AlertType = 'success' | 'error' | 'default' | 'danger';

type AlertProps = {
export interface AlertProps {
avatarSrc?: string;
content: React.ReactNode;
ctaContent?: React.ReactNode;
Expand All @@ -33,7 +33,7 @@ type AlertProps = {
truncateText?: boolean;
type?: AlertType;
[key: string]: unknown;
};
}

/**
* Alerts should be used to show notifications or messages from (providers, support, or system).
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/avatar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import PropTypes from 'prop-types';

import Style from './style';

type AvatarProps = {
export interface AvatarProps {
alt: string;
size?: 'small' | 'medium' | 'large';
src: string;
};
}

export const Avatar = ({ alt, size = 'small', src }: AvatarProps) => (
<Style.AvatarImage alt={alt} avatarSize={size} src={src} />
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/banner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ const bannerIconMapping = {

export type BannerType = 'default' | 'success' | 'error' | 'danger';

type BannerProps = {
export interface BannerProps {
content: React.ReactNode;
onClick?: () => void;
type?: BannerType;
};
}

/**
* The `<Banner />` component provides only the styling and onClick behavior of banners.
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/button/components/linkButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ButtonContents, ButtonText } from '../../style';
import { linkButtonStyles } from './style';
import { COLORS_PROP_TYPES, ThemeColors } from '../../../../constants';

type LinkProps = {
export interface LinkProps {
/**
* Specifies the tag or element to be rendered
*/
Expand All @@ -29,7 +29,7 @@ type LinkProps = {
*/
textColor?: ThemeColors;
[key: string]: unknown;
};
}

/**
* `LinkButton` will render a 'button-like' link for directing/linking to the path specified. This component can work with React Router's `Link`/`NavLink` by passing in the router component as a prop ---> `<LinkButton to='/path' as={Link}> ....`.
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/button/components/roundButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '../../deprecatedPropsHandler';
import { COLORS_PROP_TYPES, ThemeColors } from '../../../../constants';

type RoundButtonProps = {
export interface RoundButtonProps {
buttonColor?: ThemeColors;
/**
* Determines the button's main style theme
Expand All @@ -44,7 +44,7 @@ type RoundButtonProps = {
*/
textColor?: ThemeColors;
[key: string]: unknown;
};
}

/**
* `<RoundButton />` behaves mostly the same as `<Button />` except that it requires an `icon` prop since that is the main content placed with in the round button. Any children of the component will be rendered immediately below the round button.
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/button/components/textButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import PropTypes from 'prop-types';
import { ButtonContents } from '../../style';
import { BaseTextButton } from './style';

type TextButtonProps = {
export interface TextButtonProps {
/**
* Node/text to be rendered inside the button
*/
children: React.ReactNode;
disabled?: boolean;
onClick?: () => void;
[key: string]: unknown;
};
}

/**
* `TextButton` will render a block of text (or node) that will function as a button.
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type ButtonType = 'primary' | 'secondary' | 'tertiary' | 'quaternary';
*/
export type ButtonTypeWithAction = ButtonType | 'action';

type ButtonProps = {
export interface ButtonProps {
buttonColor?: ThemeColors;
/**
* Determines the button's main style theme
Expand Down Expand Up @@ -53,7 +53,7 @@ type ButtonProps = {
*/
textColor?: ThemeColors;
[key: string]: unknown;
};
}

/**
* Buttons can be used as a main call-to-action (CTA). Try to avoid using buttons of the same `buttonType` next to each other since we want to guide the user towards one option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import ButtonLoader from './style';
import { ButtonTypeWithAction } from '../..';
import { ThemeColors } from '../../../../constants';

type LoaderProps = {
export interface LoaderProps {
buttonColor: ThemeColors;
buttonType: ButtonTypeWithAction;
className?: string;
disabled: boolean;
isFullWidth?: boolean;
isLoading: boolean;
textColor?: ThemeColors;
};
}

const Loader = ({
buttonColor,
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/button/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,15 @@ function parseTheme(
}
}

type BaseButtonStylesTypes = {
export interface BaseButtonStylesTypes {
disabled: boolean;
buttonType: ButtonTypeWithAction;
buttonColor: ThemeColors;
isLoading?: boolean;
textColor?: ThemeColors;
isFullWidth?: boolean;
theme: ThemeType;
};
}

export const baseButtonStyles = ({
disabled,
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/callout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useTheme } from 'emotion-theming';
import Style from './style';
import { COLORS_PROP_TYPES, ThemeColors } from '../../constants';

type CalloutProps = {
export interface CalloutProps {
/**
* Content of the Callout element. It may contain `<strong>` tags
*/
Expand All @@ -18,7 +18,7 @@ type CalloutProps = {
* Icon displayed inside the callout right aligned
*/
icon?: React.ReactNode;
};
}

/**
* Callouts should be used to provide valuable information or additional context on a page. One of the best examples of a callout is for product recommendations.
Expand Down
4 changes: 2 additions & 2 deletions src/shared-components/carousel/arrow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { RoundButton } from '../../button';
import { ArrowLeftIcon, ArrowRightIcon } from '../../../icons';
import { ArrowContainer, BottomRightAlignedArrowContainer } from './style';

type ArrowProps = {
export interface ArrowProps {
bottomRightAlignedArrows?: boolean;
disabled?: boolean;
next?: boolean;
onClick?: () => void;
prev?: boolean;
};
}

const Arrow = ({
bottomRightAlignedArrows = false,
Expand Down
Loading

0 comments on commit 2aea377

Please sign in to comment.