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

準備

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

JavaScript

ベースの Avatar.js です。

import { forwardRef } from 'react';
import { Avatar as FlowbiteAvatar } from 'flowbite-react';

const Avatar = forwardRef((
  {
    alt = "",
    bordered = false,
    children,
    img,
    rounded = false,
    size = 'md',
    stacked = false,
    status, // 'away' | 'busy' | 'offline' | 'online'
    statusPosition = "top-right",
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteAvatar
      alt={alt}
      bordered={bordered}
      img={img}
      ref={ref}
      rounded={rounded}
      size={size}
      stacked={stacked}
      status={status}
      statusPosition={statusPosition}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar>
  );
});

const AvatarGroup = (
  {
    children,
    ...otherProps
  },
) => {
  return (
    <FlowbiteAvatar.Group {...otherProps}>
      {children}
    </FlowbiteAvatar.Group>
  );
};

const AvatarGroupCounter = (
  {
    children,
    href,
    total,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteAvatar.Counter
      href={href}
      total={total}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar.Counter>
  );
};

export default Object.assign(Avatar, {
  Group: AvatarGroup,
  GroupCounter: AvatarGroupCounter,
});

TypeScript

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

import { ComponentProps, forwardRef, LegacyRef } from 'react';
import {
  Avatar as FlowbiteAvatar,
  AvatarProps as FlowbiteAvatarProps,
} from 'flowbite-react';

type AvatarProps = {} & FlowbiteAvatarProps;

const Avatar = forwardRef((
  {
    alt = "",
    bordered = false,
    children,
    img,
    rounded = false,
    size = 'md',
    stacked = false,
    status, // 'away' | 'busy' | 'offline' | 'online'
    statusPosition = "top-right",
    ...otherProps
  }: AvatarProps,
  ref: LegacyRef<HTMLDivElement>,
) => {
  return (
    <FlowbiteAvatar
      alt={alt}
      bordered={bordered}
      img={img}
      ref={ref}
      rounded={rounded}
      size={size}
      stacked={stacked}
      status={status}
      statusPosition={statusPosition}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar>
  );
});

type AvatarGroupProps = {} & ComponentProps<typeof FlowbiteAvatar.Group>;

const AvatarGroup = (
  {
    children,
    ...otherProps
  }: AvatarGroupProps,
) => {
  return (
    <FlowbiteAvatar.Group {...otherProps}>
      {children}
    </FlowbiteAvatar.Group>
  );
};

type AvatarGroupCounterProps = {} & ComponentProps<typeof FlowbiteAvatar.Counter>;

const AvatarGroupCounter = (
  {
    children,
    href,
    total,
    ...otherProps
  }: AvatarGroupCounterProps,
) => {
  return (
    <FlowbiteAvatar.Counter
      href={href}
      total={total}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar.Counter>
  );
};

export default Object.assign(Avatar, {
  Group: AvatarGroup,
  GroupCounter: AvatarGroupCounter,
});

結果

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

はい、できました。