LoginSignup
1
2

More than 1 year has passed since last update.

【Typescript】型を強制的に変換するダブルアサーション

Last updated at Posted at 2021-12-24

typescriptには「ダブルアサーション」というものがあります。
できるだけ使うことを避けた方が良いですが、テクニックとして知っておくのが良いかと思います

アサーションとは

アサーション自体が型を強制的に変換する機能です。
以下の例を見てください。

type User = {
    id: string;
    name: string;
    isAdmin?: boolean;
}

type AdminUser = User & {
    isAdmin: true;
}

function userToAdminUser(user: User): AdminUser {
  user.isAdmin = true;
  // Type 'User' is not assignable to type 'AdminUser'.
  return user;
}

userToAdminUseruserAdminUserにして返します。

しかし、return user;でエラーが出ています。
User型からAdminUser型に変換することはできないからです。

このエラーを解決するのが、アサーションです。

  return user as AdminUser;

as AdminUserを追加することによって userをAdminUser型に変換することができます。

ダブルアサーションとは

上のようなパターンはエラーを消すことができました。
しかし、以下の例はどうでしょうか。

type User = {
    id: string;
    name: string;
    isAdmin?: boolean;
}

type AdminUser = {
    id: string;
    adminName: string;
    isAdmin: true;
}

function numberToString(hoge: User): AdminUser {
  hoge.isAdmin = true
  // Conversion of type 'User' to type 'AdminUser' may be a mistake because neither type sufficiently overlaps with the other.
  return hoge as AdminUser;
}

アサーションしているはずなのに、エラーが出ました。
上の例と違うところはAdminUser型がUser型のサブタイプではないということです。

実はtypescriptのアサーションは何でもかんでも型変換できるわけではなく、型変換したい型がサブタイプもしくはスーパータイプである必要があります。

サブタイプでない型へ変換するにはどうすれば良いでしょうか?
ここで、ダブルアサーションの出番です。

return hoge as unknown as AdminUser;

これでエラーが出なくなりました。
ダブルアサーションは一度unknown型にアサーションしてから、本来型変換したい型に変換します。
全ての型はunknown型のサブタイプなので、どんな型に変換してもエラーが出ません。
any型でも大丈夫です。
2回アサーションをしているため、ダブルアサーションという呼び方になってます。

なぜ、ダブルアサーションは避けるべきなのか

ダブルアサーションを避けた方が良い理由を一言で述べると、型安全が守られないことです。
例に挙げたコードでもhogeはAdminUser型なのにadminNameを持っていません。

function numberToString(hoge: User): AdminUser {
  hoge.isAdmin = true
  // adminNameを設定していないのにエラーが出ていない
  return hoge as unknown as AdminUser;
}
1
2
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
1
2