• トップ
  • ブログ一覧
  • TypeScriptの型を問題形式で学べる「type-challenges」とは?
  • TypeScriptの型を問題形式で学べる「type-challenges」とは?

    広告メディア事業部広告メディア事業部
    2021.03.02

    エンジニアになろう!

    type-challenges で TypeScript の型を勉強しよう!

    TypeScript 初心者にありがちな「TypeScript の型ってどう勉強すればいいの?」というお悩み。

    ひたすらドキュメントを読むのも良いですが、出来れば実際にコードを動かす方が覚えやすいと思います。

    おすすめなのが、TypeScript の型をクイズ形式で学べる「type-challenges」というサイトです。

    【type-challenges】
    https://github.com/type-challenges/type-challenges

    TypeScript の型について、初級者から上級者まで楽しみながら学べる問題が用意されています。

    この記事では、そんな「type-challenges」のメリットや進め方、解く上で必要な知識について解説していきます。

    type-challenges とは?

    type-challenges は、Github レポジトリにある「TypeScript の型に関する問題集」です。

    難易度は5段階

    以下のように、レベル別に問題が振り分けられています。

    1. お試し(全1問)
    2. 初級(全7問)
    3. 中級(全11問)
    4. 上級(全9問)
    5. 最上級(全1問)

    上級以上は、TypeScript 熟練者でもなかなか解けないくらいの難問となっています。

    また、TypeScript4.0の知識が問われる問題もあるため、最新のバージョンについてもしっかり押さえておきたいところですね。

    type-challenges で学ぶメリット

    1. パズル感覚で楽しみながら TypeScript の型を学べる
    2. 他の学習者の解答を確認できるので、知識や発想の幅が広がる
    3. Playground で気軽にコードを試せる

    type-challenges の進め方

    それでは、実際に type-challenges を進める手順を解説していきます。

    問題を選択する

    まずは type-challenges にアクセスし、「課題集」の中から問題を選びましょう。

    問題を選択する

    まずは「お試し」から始めて、問題の解き方を理解するのが良いでしょう。

    「お試し」の下にあるバッジをクリックすると、問題のページに移動できます。

    「お試し」の下にあるバッジをクリックすると、問題のページに移動できる

    Playground で実際に TypeScript のコードを記述する

    問題を確認できたら、実際にコードを書いてみましょう。

    自分のローカル環境でコーディングしても構いませんが、「TypeScript Playground」なら気軽にコードを試せるのでおすすめです。

    【TypeScripy Playground】
    https://www.typescriptlang.org/play

    問題ページの中に、「TS 挑戦する」というバッジがあるので、それをクリックしましょう。

    そうすると、以下のように、必要なコードが揃った状態でコーディングが始められます。

    必要なコードが揃った状態でコーディングが始められる

    型のエラーが発生しなければ正解なので、試行錯誤しながら答えを導き出してください!

    答えを確認する

    型のエラーが無くなったら、「解答を確認」をクリックして、その問題の答えを確認してみましょう。

    解答ページは Github の Issue になっているので、世界中のエンジニアの解答を閲覧できます。

    答えを確認する

    「お試し」問題は、HelloWorld を string 型にするだけでOKですね。

    また、もし自分の解答がこの Issue になかったら、「解答を共有」から投稿することもできます。

    これだけは知っておきたい、TypeScript の知識

    type-challenges は、たとえ初級でも最低限の TypeScript の知識が必要です。

    ここでは、type-challenges に挑戦する前に、マスターしておきたいポイントを紹介します。

    ジェネリクス

    ジェネリクスは「総称型」とも呼ばれており、動的に型を決めたい場合に使用されます。

    関数でジェネリクスを使う場合

    例えば、関数でジェネリクスを利用する場合、以下のような書き方をします。

    1function test<T>(a: T) { 
    2    return a;
    3}

    この関数は、T 型の引数を受け取って、T 型を返す関数です。

    例えば、受け取った引数が string 型なら string 型を返すというわけです。

    この関数は、以下のようにして呼び出します。

    1test(777)
    2test('str')

    このように、test 関数の引数は、string 型が入った時には string 型になります。

    ジェネリクスでエラーを防ごう

    でも、これだけでは any 型とあまり変わらないので、ジェネリクスのメリットを生かすには以下のようにします。

    1function test2<T>(x: T, y: T): void {
    2    console.log(x)
    3    console.log(y)
    4}

    こちらの例では、第一引数の型と第二引数の型が両方 T になっていますね。

    これは「第一引数と第二引数の型が同じでなければいけない」という制約を課しています。

    つまり、以下のコードがコンパイルエラーになるのです(第一引数が number 型で、第二引数が string 型のため)。

    1test2(100, 'Hello')

    可変長引数

    関数の引数がいくつかわからなくても、「可変長引数」なら、配列でまとめて受け取ることができます。

    TypeScript では、可変長引数の関数を以下のようにして定義します。

    1function test (...words: string[]): string {
    2  return "Hello, " + words.join("-");
    3}
    4
    5console.log(test("type", "challenges"));
    6// "Hello, type-challenges"

    引数の前に... を追加することで、可変長引数になります。

    ちなみに、可変長引数は JavaScript でも使用可能です。

    (ただし、IE はサポート対象外です)

    直和型(Union Type)

    「直和型」とは、様々な型を組み合わせられる機能です。

    例えば、number 型と null を許容する型を作りたい場合、TypeScript では以下のように書きます。

    1type NullableNum = number | null

    特定の文字列を指定できる

    TypeScript における直和型のメリットは、「特定の文字列を型に指定できる」ところです。

    例えば、文字列「apple」「orange」「grape」だけを許容する Fruits 型を作りたい場合、他の言語だと enum(列挙型)で実装することが多いのですが、TypeScript では以下のようになります。

    1type Fruits = 'apple' | 'orange' | 'grape';
    2let a: Fruits = 'apple' // OK
    3let b: Fruits = 'APPLE' // NG

    数字+文字列も OK

    また、以下のように、特定の数字と文字列だけを型として設定することもできます。

    1type FiveNumber = 1 | 2 | 3 | 4 | 5 | 'message';

    この例では、数字「1~5」と文字列「message」だけを許容する型を作っています。

    keyof

    「keyof」を使うと、指定した型のプロパティ名の直和型を表現できます。

    例えば、以下のような Person 型を定義したとしましょう。

    1interface Person {
    2  name: string;
    3  age: number;
    4}

    この Person に keyof を適用した型を定義すると、'name' | 'age' という直和型に変換されます。

    1type PersonKey = keyof Person
    2// PersonKeyの型は、'name' | 'age'

    このように、Person の型を、文字列「name」と「age」のみを許容する PersonKey 型に変換することができるのです。

    Mapped types

    「Mapped types」は、元の型に応じて新しい型を作れる機能です。

    配列から1つずつ要素を取り出すfor ... of と書き方が似ていますね。

    1{[P in K]: T}

    例えば、プロパティ名を「x、y」、型を number としたい時は、以下のように定義します。

    1type T1 = { [P in "x" | "y"]: number };  
    2// { x: number, y: number }

    また、プロパティを全て readonly にしたい時などにも、Mapped Types が使えます。

    1interface Person {
    2  name: string;
    3  age: number;
    4};
    5
    6type ReadonlyPerson = {
    7  readonly [p in keyof Person]: Person[p];
    8};

    type-challenges を解く上で役に立つ Web サイト

    type-challenges と併せて使いたい、TypeScript の型について学べる Web サイトをまとめてみました。

    TypeScript の型入門 - Qiita

    名前の通り、初心者にまずおすすめしたい記事です。

    TypeScript の型について、一通り把握できますよ。

    【TypeScript の型入門 - Quiita】
    https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a

    仕事ですぐに使える TypeScript

    こちらは、より実践的なドキュメントになっています。

    特に参考になるのは、ジェネリクスの部分です。

    type-challenges ではジェネリクスを使うことが多いので、きっちりマスターしておきましょう。

    【仕事ですぐに使える TypeScript】
    https://future-architect.github.io/typescript-guide/

    TypeScript Deep Dive 日本語版

    TypeScript の型を学んでいる人なら、一度はこのサイトを目にしたことがあるのではないでしょうか。

    TypeScript の型についてわかりやすく書かれており、高度な型の機能に関しても解説されているため、習熟度にかかわらず役立つサイトです。

    【TypeScript Deep Dive 日本語版】
    https://typescript-jp.gitbook.io/deep-dive/type-system

    さいごに

    以上、type-challenges の特徴や進め方、解く上で必須となる知識について解説しました。

    type-challenges は、パズル感覚で楽しく TypeScript の型が学べます。

    ご紹介した web サイトも併せれば、きっと学習がはかどることと思います。

    ぜひ、type-challenges を駆使して、TypeScript の型をマスターしてくださいね!

    こちらの記事もオススメ!

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
    featureImg2020.08.07JavaScript 特集知識編JavaScriptを使ってできることをわかりやすく解説!JavaScriptの歴史【紆余曲折を経たプログラミン...

    広告メディア事業部

    広告メディア事業部

    おすすめ記事