見出し画像

【ワンピースで覚えるTypeScript】第24回 高度な型(JavaScript学習者向け)

今回はTypeScriptの型について、さらに踏み込んで説明します。

便利な組み込みの型もあるので、覚えてほしいと思います。


type StrawHatPirate = {
  name: string;
  bounty: number;
  captain: "luffy";
};

function isStrawHatPirate(crew: any): crew is StrawHatPirate {
  if(crew == null) return false;
  return (
    crew.captain === "luffy" && 
    typeof crew.name === "string" &&
    typeof crew.bounty === "number"
  );
}
//isStrawHatPirateというユーザー定義型ガード
//麦わらの一味の型かどうか調べる

function introduce(pirate: unknown){
  if (isStrawHatPirate(pirate)){
    console.log("麦わらの一味です");
  } else {
    console.log("麦わらの一味ではありません");
  }
}

const chopper: StrawHatPirate = {
  name: "チョッパー",
  bounty: 1000,
  captain: "luffy",
}
introduce(chopper);

const bepo = {
  name: "ベポ",
  bounty: 500,
  captain: "law",
}
introduce(bepo);

//asserts 引数名 is 型
//関数が例外を投げずに無事に終了したならば、型述語の条件が満たされる
function assestStrawHatPirate(crew: any): asserts crew is StrawHatPirate {
  if (crew == null) {
    throw new Error("nullやundefinedはだめだよ");
  }
  if(
    crew.captain !== "luffy" ||
    typeof crew.name !== "string" ||
    typeof crew.bounty !== "number"
  ){
    throw new Error("麦わらの一味じゃないよ");
  };
}
//例外の有無を判定するのに便利
function checkStrawHatPirate(value: unknown): void{
  assestStrawHatPirate(value);
  console.log("麦わらの一味だ!!")
}

checkStrawHatPirate(chopper);
//checkStrawHatPirate(bepo);

//可変長タプル型
type AgeAndString = [number, ...string[]];

const nami: AgeAndString = [20, "ナミ"];
const nami2: AgeAndString = [20, "ナミ", "泥棒猫"];
const nami3: AgeAndString = [20];

//const nami4: AgeAndString = ["ナミ", 20, "ナミ"];
//const nami5: AgeAndString = [20, 170, "ナミ"];
//const nami6: AgeAndString = [];

//タプル型は1回しか使えない
//type T1 = [number, ...string[], ...string[]];
//オプショナルな要素より前で使えない
//type T2 = [...string[], number?];
type T3 = [number?, ...string[]];

//別のタプル型(配列型)に展開できる
type SSN = [string, string, number];
type NSSNS = [number, ...SSN, string]

//mapped types
type CharaString = "name" | "devil_fruits" | "captain";

type Character = {
  [P in CharaString]: string
}

const robin: Character = {
  name: "ロビン",
  devil_fruits: "ハナハナの実",
  captain: "ルフィ"
}

//conditional types
type Ability = {
  devil_fruits: string;
}

type isAbility<T> = T extends Ability ? true : false;

const luffy = {
  name: "ルフィ",
  devil_fruits: "ゴムゴムの実",
}
const sanji = {
  name: "サンジ",
}
type T1 = isAbility<typeof luffy>
type T2 = isAbility<typeof sanji>

//組み込みの型
//Partial<T>
//=> すべてのプロパティをオプショナルにする
type T3 = Partial<{
  name: string;
  devil_fruits: string;
}>

//Pick<T, K>
//=> TのうちKのプロパティのみ残す
type T4 = Pick<{
name: string;
devil_fruits: string;
}, "devil_fruits">

//Omit<T, K>
//=> TのうちKのプロパティを取り除く
type T5 = Omit<{
  name: string;
  devil_fruits: string;
}, "devil_fruits">

この記事が気に入ったらサポートをしてみませんか?