宮水の日記

宮水の日記

主に書評や資格取得について記事を書いています。

Typescript exercises やってみた 1問目

みなさんこんにちは。宮水です。
今日は、TypeScript エクササイズの1に取り組んでみました。
英語も苦手なので、翻訳も自分でしてみました。

こちらのリポジトリをforkして、cloneして取り組みます。
rootディレクトリで、yarn installしてから問題文にあるRun this exerciseのコマンドを叩くと、答え合わせができます。すごい!!
github.com

前回の問題

miyamizu.hatenadiary.jp

本日の問題

import chalk from 'chalk';

/*

Intro:

    All 2 users liked the idea of the community. We should go
    forward and introduce some order. We are in Germany after all.
    Let's add a couple of admins.

    Initially we only had users in the in-memory database. After
    introducing Admins, we need to fix the types so that
    everything works well together.

 2人のユーザーが、コミュニティのアイデアを気に入りました。
 それでは、いくつかのを注文を取り込みます。(意訳めっちゃ下手www)
 私たちは所謂ドイツにいます。2人を"管理者"として追加しましょう。

 最初はインメモリデータベースには、Userしかいませんでした。
 "管理者(Admin)"型を追加し、全ての機能をうまく機能するために型を変更する必要があります。

Exercise:

    Type "Person" is missing, please define it and use
    it in persons array and logPerson function in order to fix
    all the TS errors.

 型「Person」を追加し、使用してください。
 persons arrayとlogPerson関数のTSエラーを修正してください。

Run this exercise:

    npm run 1

    - OR -

    yarn -s 1

*/

interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

const persons: User[] /* <- Person[] */ = [
    {
        name: 'Max Mustermann',
        age: 25,
        occupation: 'Chimney sweep'
    },
    {
        name: 'Jane Doe',
        age: 32,
        role: 'Administrator'
    },
    {
        name: 'Kate Müller',
        age: 23,
        occupation: 'Astronaut'
    },
    {
        name: 'Bruce Willis',
        age: 64,
        role: 'World saver'
    }
];

function logPerson(user: User) {
    console.log(` - ${chalk.green(user.name)}, ${user.age}`);
}

persons.forEach(logPerson);

// In case if you are stuck:
// https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types

答え

interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

type Person = User | Admin;

const persons: Person[] /* <- Person[] */ = [
    {
        name: 'Max Mustermann',
        age: 25,
        occupation: 'Chimney sweep'
    },
    {
        name: 'Jane Doe',
        age: 32,
        role: 'Administrator'
    },
    {
        name: 'Kate Müller',
        age: 23,
        occupation: 'Astronaut'
    },
    {
        name: 'Bruce Willis',
        age: 64,
        role: 'World saver'
    }
];

function logPerson(user: Person) {
    console.log(` - ${chalk.green(user.name)}, ${user.age}`);
}

persons.forEach(logPerson);

いい感じ😻
f:id:kattyan53:20200723233638p:plain

感想

ユニオン型

今回は、"Union Types"に関する問題でした。
ユニオン型とは、A | B と書かれ、Aの値でもBの値でも許されます。
今回は、UserとAdminにたいして使用しましたが、以下のような書き方も、ユニオン型です。

// UserIdは、文字列でも数値でもおっけー👌
type UserId = string | number;
interfaceとtype

interfaceとtypeの違いは、この記事を読むのが良さそうです👌
freelance-jak.com

qiita.com


ざっと調べた感じ、この場合にはどっちを使え!っていう決まりは無いようです。

今回のエクササイズの問題を見ると、UserやAdminはオブジェクトなのでinterfaceとして定義して、Personは型の組み合わせに別名をつけているのでtypeを使用しているのかなと思いました。

どっちも使い方が似ていますが、違いを理解して使い分けられるようになると良さそうです。

以上です!