[React+Tailwind] Footer を TypeScript に書き直してみた | 心を無にして始める React

準備

書き直すベースはこちらの Footer コンポーネントです。

JavaScript

ベースの Footer.js です。

import { forwardRef } from 'react';
import { Footer as FlowbiteFooter } from 'flowbite-react';

const Footer = forwardRef((
  {
    bgDark = false,
    children,
    container = false,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter
      bgDark={bgDark}
      container={container}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter>
  );
});

const FooterBrand = forwardRef((
  {
    alt,
    children,
    href,
    name,
    src,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Brand
      alt={alt}
      href={href}
      name={name}
      ref={ref}
      src={src}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Brand>
  );
});

const FooterCopyright = forwardRef((
  {
    by,
    children,
    href,
    year,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Copyright
      by={by}
      href={href}
      ref={ref}
      year={year}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Copyright>
  );
});

const FooterDivider = (
  {
    ...otherProps
  },
) => {
  return (
    <FlowbiteFooter.Divider
      {...otherProps}
    />
  );
};

const FooterIcon = forwardRef((
  {
    ariaLabel,
    children,
    href,
    icon,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Icon
      ariaLabel={ariaLabel}
      href={href}
      icon={icon}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Icon>
  );
});

const FooterLink = forwardRef((
  {
    children,
    href,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Link
      href={href}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Link>
  );
});

const FooterLinkGroup = forwardRef((
  {
    children,
    col = false,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.LinkGroup
      col={col}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.LinkGroup>
  );
});

const FooterTitle = forwardRef((
  {
    children,
    title,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Title
      ref={ref}
      title={title}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Title>
  );
});

export default Object.assign(Footer, {
  Brand: FooterBrand,
  Copyright: FooterCopyright,
  Divider: FooterDivider,
  Icon: FooterIcon,
  Link: FooterLink,
  LinkGroup: FooterLinkGroup,
  Title: FooterTitle,
});

TypeScript

Footer.tsx として編集します。

import { ComponentProps, forwardRef, LegacyRef } from 'react';
import {
  Footer as FlowbiteFooter,
  FooterProps as FlowbiteFooterProps,
} from 'flowbite-react';

type FooterProps = {} & FlowbiteFooterProps

const Footer = forwardRef((
  {
    bgDark = false,
    children,
    container = false,
    ...otherProps
  }: FooterProps,
  ref: LegacyRef<HTMLElement>,
) => {
  return (
    <FlowbiteFooter
      bgDark={bgDark}
      container={container}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter>
  );
});

type FooterBrandProps = {} & ComponentProps<typeof FlowbiteFooter.Brand>

const FooterBrand = forwardRef((
  {
    alt,
    children,
    href,
    name,
    src,
    ...otherProps
  }: FooterBrandProps,
  ref: LegacyRef<HTMLDivElement>,
) => {
  return (
    <FlowbiteFooter.Brand
      alt={alt}
      href={href}
      name={name}
      ref={ref}
      src={src}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Brand>
  );
});

type FooterCopyrightProps = {} & ComponentProps<typeof FlowbiteFooter.Copyright>

const FooterCopyright = forwardRef((
  {
    by,
    children,
    href,
    year,
    ...otherProps
  }: FooterCopyrightProps,
  ref: LegacyRef<HTMLSpanElement>,
) => {
  return (
    <FlowbiteFooter.Copyright
      by={by}
      href={href}
      ref={ref}
      year={year}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Copyright>
  );
});

type FooterDividerProps = {} & ComponentProps<typeof FlowbiteFooter.Divider>

const FooterDivider = (
  {
    ...otherProps
  }: FooterDividerProps,
) => {
  return (
    <FlowbiteFooter.Divider
      {...otherProps}
    />
  );
};

type FooterIconProps = {} & ComponentProps<typeof FlowbiteFooter.Icon>

const FooterIcon = forwardRef((
  {
    ariaLabel,
    children,
    href,
    icon,
    ...otherProps
  }: FooterIconProps,
  ref: LegacyRef<HTMLAnchorElement>,
) => {
  return (
    <FlowbiteFooter.Icon
      ariaLabel={ariaLabel}
      href={href}
      icon={icon}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Icon>
  );
});

type FooterLinkProps = {} & ComponentProps<typeof FlowbiteFooter.Link>

const FooterLink = forwardRef((
  {
    children,
    href,
    ...otherProps
  }: FooterLinkProps,
  ref: LegacyRef<HTMLAnchorElement>,
) => {
  return (
    <FlowbiteFooter.Link
      href={href}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Link>
  );
});

type FooterLinkGroupProps = {} & ComponentProps<typeof FlowbiteFooter.LinkGroup>

const FooterLinkGroup = forwardRef((
  {
    children,
    col = false,
    ...otherProps
  }: FooterLinkGroupProps,
  ref: LegacyRef<HTMLUListElement>,
) => {
  return (
    <FlowbiteFooter.LinkGroup
      col={col}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.LinkGroup>
  );
});

type FooterTitleProps = {} & ComponentProps<typeof FlowbiteFooter.Title>

const FooterTitle = forwardRef((
  {
    children,
    title,
    ...otherProps
  }: FooterTitleProps,
  ref: LegacyRef<HTMLHeadingElement>,
) => {
  return (
    <FlowbiteFooter.Title
      ref={ref}
      title={title}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Title>
  );
});

export default Object.assign(Footer, {
  Brand: FooterBrand,
  Copyright: FooterCopyright,
  Divider: FooterDivider,
  Icon: FooterIcon,
  Link: FooterLink,
  LinkGroup: FooterLinkGroup,
  Title: FooterTitle,
});

結果

変化はないので、前と同じ。

はい、できました。