tomatommy
@tomatommy

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

2つのtypeを継承したtypeから、親typeを判断する方法

解決したいこと

typescriptの型定義で、2つの疑問があります

  1. type fruit = "apple" | "orange"等の型定義の仕方をなんというのか。
  2. 2つの型定義を継承した型について、どちらの型に属するのか判定する方法

type fruit = "apple" | "orange"等の型定義の仕方をなんというのか

表題の通り。
typeを用いた宣言、ではなく、 "sample1" | "sample2"の宣言の仕方です。

2つの型定義を継承した型について、どちらの方に属するのか判定する方法

例として

type fruit = "apple" | "orange"
type vegetable = "carrot" | "tomato"
type food = fruit & vegetable

function isFruit(arg:food) : arg is fruit{
  // TODO
}

function isVegetable(arg:food) : arg is vegetable{
  // TODO
}

このTODOの記述の仕方を教えていただきたいです。

0

1Answer

  1. union型と呼ばれます
  2. 実行時に消えてしまう型情報による処理分けをするためには、まず値を持った配列を元に型を定義し、型の判別にはその配列を使用するなどといった方法が取られるようです
const fruit_values = ["apple", "orange"] as const; //as constでreadonlyに
type fruit = typeof fruit_values[number]; //"apple" | "orange" 型として取得

const vegetable_values = ["carrot", "tomato"] as const;
type vegetable = typeof vegetable_values[number]; //"carrot" | "tomato"

type food = fruit | vegetable; //"&"だとnever型になってしまうので修正

function isFruit(arg:food): arg is fruit {
  return fruit_values.includes(arg as fruit); //argが配列に含まれていればfruit型とする
}

function isVegetable(arg:food): arg is vegetable {
  return vegetable_values.includes(arg as vegetable);
}


// 適当なfood型配列からfruit型の値のみを抽出し、fruit型配列へ追加してみるテスト

const some_foods: food[] = ["apple", "carrot", "orange", "tomato"];
const fruitsBasket: fruit[] = [];

for( const anyfood of some_foods ) {
  if( isFruit(anyfood) ) {
    fruitsBasket.push(anyfood);
  }

  //型ガードisFruitを通していないとコンパイルエラー(正しい挙動)
  //fruitsBasket.push(anyfood);
}

console.log(fruitsBasket); // ["apple", "orange"]


1Like

Comments

  1. @tomatommy

    Questioner

    まさに芯を捉えた回答ありがとうございます。

Your answer might help someone💌