0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「: p is Admin」って何?型述語(Type Predicate)

0
Posted at

TypeScript特有の書き方

function isAdmin(person: Person): person is Admin

このコードを見て「なにこの書き方?」って思ったことあるでしょうか?

実はこれ、TypeScriptの機能のひとつである “型述語(Type Predicate)”。
戻り値の型っぽいが、実は型推論を操るための特殊な構文です。
今回はその正体と、実務でどう使えるかをわかりやすく紹介していきます。

前提

interface User {
  type: 'user';
  name: string;
  occupation: string;
}

interface Admin {
  type: 'admin';
  name: string;
  role: string;
}

type Person = User | Admin;

UserとAdminという二つの状態があり、これら二つを合わせた型をPerson型とします。

まずは普通の関数の場合

function isAdmin(person: Person): boolean {
  return person.type === 'admin';
}

if (isAdmin(person)) {
  console.log(person.role); // ❌ エラー!
}

この書き方だと isAdmin は「ただのbooleanを返す関数」。TypeScriptは「trueかfalseを返すだけ」としか認識しないため、person.role にアクセスすると「そんなプロパティないよ!」と怒られます。(なぜならpersonがUserかAdminかをTypeScript側で解釈できないため)

そこで登場する「型述語(Type Predicate)」

function isAdmin(person: Person): person is Admin {
  return person.type === 'admin';
}

if (isAdmin(person)) {
  console.log(person.role); // ✅ OK!
}

person is Admin の部分が型述語。
これは「この関数がtrueを返すとき、person は Admin 型だよ」とTypeScriptの型システムに教えている特別な文法です。

型述語の使いどころ

function isAdmin(p: Person): p is Admin {
  return p.type === 'admin';
}

function isUser(p: Person): p is User {
  return p.type === 'user';
}

const persons: Person[] = [
  { type: 'user', name: 'Kate', occupation: 'Astronaut' },
  { type: 'admin', name: 'Bruce', role: 'World saver' }
];

persons.filter(isAdmin).forEach(admin => {
  console.log(admin.role); // ✅ OK
});

persons.filter(isUser).forEach(user => {
  console.log(user.occupation); // ✅ OK
});

filter( ) に直接 isAdmin を渡せるのがポイントですね。
こうすることで、返ってくる配列の型が Admin[ ] に自動で絞り込まれます。
つまり、安全で、かつ可読性の高いコードになります。

まとめ

  • ( ): p is T は Type Predicate(型述語) という特殊な構文

  • 戻り値の型注釈とは似て非なるもの

  • TypeScriptに「この条件のときはこの型」と教えられる

  • 結果、コードが安全で読みやすくなる

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?