DEV Community

kaede
kaede

Posted on

手を動かしながら学ぶ TypeScript Part 3 --高度な型

why

応用的な型の一つの記事では収まらなかったので。


参考

手を動かしながら学ぶ TypeScript
by SmartHR
SECTION-025 TypeScript の型や構文の紹介
P.277 ~

https://www.amazon.co.jp/%E6%89%8B%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6-TypeScript-%E6%B8%A1%E9%82%89%E6%AF%94%E5%91%82%E6%A8%B9-ebook/dp/B09KZJXDN1


目次

  1. generics
  2. tupple
  3. typeof
  4. Index Signature
  5. Mapped Types
  6. keyof
  7. enum
  8. conditinal types
  9. Partial
  10. Requied
  11. Omit

Generics

受け取った型に応じた処理ができる?

function printMessage<T> (arg: T):T {
  console.log(typeof arg);
  console.log(arg);
  return arg
}

printMessage("text")
printMessage(33)
Enter fullscreen mode Exit fullscreen mode

引数の型を表示して返す関数が作れる

ts-node generics.ts
string
text
number
33
Enter fullscreen mode Exit fullscreen mode

"text" を渡せば string
33 を渡せば number が返ってくる

型をなんでも受け取って、なんの型かを返す関数は
any でも同じことができてしまいそう


tupple

完全に入るものが決まった型。

type bucket = string[]
const fruits:bucket = ['apple', 'banana', 'tomato']

type tuppleBucket = ['apple', 'banana']
const tuppleFruit:tuppleBucket = ['apple', 'kwi']
Enter fullscreen mode Exit fullscreen mode

Type '"kwi"' is not assignable to type '"banana"'

bucket は文字列のみがいくらでも入る配列だが
tuppleBucket は 'apple', 'banana', のみが入る型になった。


typeof

const sayHello = (name: string) => {
  console.log(`Hello: ${name}`);
}
type sayHello = typeof sayHello
Enter fullscreen mode Exit fullscreen mode

string が void で返る型を type に再代入することができる。
あまり普段使わなそう。
string, number, bool, などの単純な型を見る時には使えるが。


Index Signature

key の名前と型、value の型
これらだけを決めて、型を使って入る数は自由にする。

https://zenn.dev/tsuboi/articles/ee43ddc5a2cd941de138#%E2%91%A0%E3%82%AD%E3%83%BC%E3%81%AE%E5%9E%8B%E3%81%AFstring%E5%9E%8B%E3%81%8Bnumber%E5%9E%8B

Tsuboi さんの記事が分かりやすかったので引用させてもらう

type Ranking = {
  [rank: number]: string;
};
const ranking: Ranking = {
  1: "Mikasa Ackermann",
  2: "Reiner Brown",
  3: "Bertolt Hoover",
};
Enter fullscreen mode Exit fullscreen mode

この例だと

  • key のランクで数値型、
  • value が文字列型
  • 入る数は自由

と指定して、

  • rank1: ミカサ
  • rank2: ライナー
  • rank3: ベルトルト

と値を入れることができる


Mapped Types

ユニオン型からオブジェクトのキーを生成して型を作れるらしい。
用途不明。


keyof

interface から各オブジェクトの key を取って ユニオン型にできる。

interface Cat {
  name: string,
  age: number
}
type CatKey = keyof Cat
Enter fullscreen mode Exit fullscreen mode

この CatKey は "name" | "age" になる。

const NyaakoName:CatKey = "name"
const NyaakoAge:CatKey = "age"
const Tama:CatKey = { name: "Tama"} 
Enter fullscreen mode Exit fullscreen mode

なので最後の Tama は

Type '{ name: string; }' is not assignable to type 'keyof Cat'.

Cat の key たちには入りませんというエラーが出る。


enum

列挙型

Image description

補完が効いて便利。

enum SIZE {
  S,M,L,
}

const myShirt = SIZE.M
const myLongShirt = SIZE[2]
const myPotato:SIZE = SIZE.L
Enter fullscreen mode Exit fullscreen mode

SIZE.M でプロパティのように利用したり
SIZE[2] で配列のように利用したり
:SIZE と型として利用することともできる。
しかし、型の表記があってもなくても enum の中身以外入らないし、
型扱いされるので必要ないかも?


Assertion Functions

難解。未検証


Conditional Types

条件によって変わる型。型の中でロジックを計算できるのが画期的そう。

https://zenn.dev/pvcresin/articles/073dc774eb241c

pvcresin さんのこの記事が分かりやすかった

type IsString<T> = T extends string ? true : false
Enter fullscreen mode Exit fullscreen mode

変数の isOpen みたいなノリで条件を入れて型を作れる。
この場合はジェネリクスで型を引数から持ってきて、
string だったら true
違ったら false を返す型になっている。

type name = IsString<'kaede'>
type age = IsString<2>
Enter fullscreen mode Exit fullscreen mode

isString を使って 'kaede' という文字列の型と
2 という数値の型を作る

数値でもエラーにならず作れてしまうが、

Image description

Image description

型の名前をホバーすると、age では false が出ている。


Partial

type name?:string のようにすると optional になって
その項目がなくてもエラーにならなくなるが

その型に後から

const VariableName: TypeName<Partial> = {}
Enter fullscreen mode Exit fullscreen mode

とすると無理矢理 optional にできる。


Required

Partial の逆。同じやり方で必須にできる。


Omit

型オブジェクトの一部を無視して使用できる。

const variableName: Omit<TypeName, 'TypeItemName'> = {}
Enter fullscreen mode Exit fullscreen mode

これで TypeItemName を定義しなくても、無理矢理 TypeName の型を使うことができる。

type Turtle = {
  name: string,
  age: number,
}

const KameTaro: Omit<Turtle,'age'> = { name: "Kametaro"}
Enter fullscreen mode Exit fullscreen mode

これで、age を無視して Turtle 型を使った変数を定義することができた。

Top comments (0)