3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

分割代入に型アサーションを使うメモ(Typescript)

Last updated at Posted at 2022-02-20

結論

as でオブジェクト型を定義してダウンキャストすれば良いです。

事の経緯

きっかけは Next.js でダイナミックルーティングの際に、router.queryを使用したのだが、返却型がstring | string[]となります。

使用するコンポーネントに対して型エラーが起きたのでそれを解決する方法をメモとして残します。

import { useRouter } from "next/router";

export const ParentComponent = () => {
  const router = useRouter();

  // as により型をダウンキャストする
  const { hoge, piyo } = router.query as {
    hoge: string;
    piyo: string;
  };

  return <ChildComponent hoge={hoge} piyo={piyo} />;
};
type ChildComponentProps = {
  hoge: string;
  piyo: string;
};
const ChildComponent: React.VFC<ChildComponentProps> = ({ hoge, piyo }) => {
  return (
    <>
      <div>{hoge}</div>
      <div>{piyo}</div>
    </>
  );
};

だめな例

型キャストがない状態だと以下のエラーが出力されます。

Type 'string | string[]' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.ts(2322)

import { useRouter } from "next/router";

export const ParentComponent = () => {
  const router = useRouter();

  // hoge, piyoは 'string | string[]' 型
  const { hoge, piyo } = router.query;
  // ChildComponent の hoge はstring型なので Error
  return <ChildComponent hoge={hoge} piyo={piyo} />;
};

他の方法

また分割代入したそれぞれの変数に対して、ChildComponent に渡す際にダウンキャストしても良いです。個人的にはなんかイケてない書き方な気もします。

import { useRouter } from "next/router";

export const ParentComponent = () => {
  const router = useRouter();

  const { hoge, piyo } = router.query;

  return <ChildComponent hoge={hoge as string} piyo={piyo as string} />;
};

では number 型にキャストする場合はどうなのか?

子コンポーネントのPropsが以下の場合、numberにキャストする必要があります。

type ChildComponentProps = {
  hoge: number;
  piyo: number;
};

as unknown により型をアップキャストしダウンキャストするとうまく型エラーを回避できます。

import { useRouter } from "next/router";

export const ParentComponent = () => {
  const router = useRouter();

  // as unknown により型をアップキャストし、その後ダウンキャストする
  const { hoge, piyo } = router.query as unknown as {
    hoge: number;
    piyo: number;
  };

  return <ChildComponent hoge={hoge} piyo={piyo} />;
};

参考文献

TypeScript の型入門

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?