TypeScriptの関数、インターフェイス、クラスの使い方・実例8件

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、前回記事「TypeScriptの型宣言・全15実例」ではTypeScriptの基本を知るために基本中の基本である「型の宣言」をまとめてみました。

そして、今回も基本テクニックの、

関数、インターフェイス、クラス

の使い方をご紹介したいと思います。

なお、TypeScriptは、基本的にJavaScriptES6(ES2015)の書き方を踏襲していますので、TypeScriptだけでなく純粋なJavaScriptの知識としても分かりやすいようにまとめてみました。

ぜひ楽しみながらやってみましょう!😊✨

「最近はES6がメインです✨」

開発環境: TypeScript 3.8.3

関数

データ型を指定する

例えば、名前と年齢を入力したら「●●さん(▲▲歳)」と返す関数を見てみましょう。

function userInfo(name: string, age: number): string {

    return `${name} さん(${age}歳)`;

}

console.log(
    userInfo('太郎', 25)
);

この中で、型の宣言が入っているのは以下2ヶ所です。

  • 引数の部分(2つ)
  • 返り値の部分

このように「入るところ&出るところ」で型宣言をすることでよりエラーを減らすことにつながります。

引数を省略する

例えば、「名前は必須だけど、年齢は任意でOK」という関数を作りたい場合です。
この場合、年齢の引数age?をつけます。

function userInfo(name: string, age?: number): string {

    let info = `${name} さん`;

    if(age) { // 年齢がある場合だけ実行

        info += `(${age}歳)`;

    }

    return info;

}

console.log(
    userInfo('太郎') // 「太郎 さん」
);

console.log(
    userInfo('太郎', 25) // 「太郎 さん(25歳)」
);

なお、引数が省略された場合中身はundefinedになります。

デフォルト値をつける

例えば、名前の入力がない場合、代わりに「匿名希望」が引数に格納されるようにしたい場合です。

この場合、引数に続いて=で初期値を書きます。

function userName(name: string = '匿名希望'): string {

    return `${name} さん`;

}

console.log(
    userName() // 「匿名希望 さん」
);
console.log(
    userName('山田太郎') // 「山田太郎 さん」
);

引数を可変にする

例えば、引数の数を指定せず可変にする場合です。
この場合引数に...をつけます。

例として、趣味を指定する場合を見てみましょう。

function myHobby(...hobbyNames: string[]): void {

    console.log(hobbyNames);

}

myHobby('野球', 'ピアノ', 'お花', 'バーベキュー'); // 👈 引数は無限に追加できます。

関数に型指定する

例えば、「何の商品をいくつ注文するか❓」を指定する関数をつくってみましょう。

let orderInfo: (name: string, count: number) => [string, number] =
    function(productName: string, quantity: number): [string, number] {

        return [productName, quantity];

    };

少し複雑ですが、この場合1行目の太字の部分が型の指定になります。

つまり、次の関数は「1つ目の引数は文字列、2つ目が数値、そして返り値は配列(正確には、文字列と数値のタプル)」ですよ、という指定です。

インターフェイス

例えば、引数がたくさん必要な場合、コードがごちゃごちゃしてしまいます。

// 引数の部分が長すぎて見にくい😫
function fullAddress(address: { zip: string, pref: string, city: string, street: string }): string {

    return `〒${address.zip} ${address.pref} ${address.city} ${address.street}`;

}

そんな場合に役立つのがインターフェイスです。
実際の例を見てみましょう。

interface Address { // 👈 住所のインターフェイス
    zip: string,
    pref: string,
    city: string,
    street: string
}

function fullAddress(address: Address): string { // 👈 ここで指定

    return `〒${address.zip} ${address.pref} ${address.city} ${address.street}`;

}

つまり、引数の部分を別の場所で定義するのでスッキリしたコードを書くことができるというわけです。

しかもインターフェイスは使いまわしができるので一度定義しておくと後でラクができますね😊✨

クラス

基本的な使い方

基本的なクラスの使い方は次のとおりです。

class User {

    private name: string; // 👈 クラス内からしか取得できない

    constructor(name: string) {

        this.name = name;

    }

    public message(): string { // 👈 どこからでもアクセス可

        return `こんにちは、${this.name} さん!`;

    }

}

const user = new User('山田太郎');
console.log(
    user.message()
);

このなかで重要なのはアクセス・スコープです。

アクセス・スコープとは、変数やメソッドのアクセス範囲を指定するもので、例えば以下のようなものがあります。

  • private: そのクラス内だけ
  • protected: そのクラス&継承されたクラスだけ
  • public: どこからでもOK

つまり今回の例で言うと、変数nameprivateが指定されているので、クラスの中からしかアクセスできません。userからはアクセスできない)

逆にmessage()は、public指定されているので、どこからでもアクセスができます。

クラスの継承(拡張)

例えば、先ほどのUserクラスに年齢をセットするメソッドsetAge()を追加したい場合です。

もちろん直接Userクラスにコードを足してもいいですが、もし管理者ユーザーだけに年齢情報が必要な場合、Userを継承したAdminクラスをつくっておけば間違った使い方が減ることになります。

そこで、Userクラスを継承してAdminクラスをつくってみましょう。

【1.Userクラス】

class User {

    protected name: string; // 👈 このクラスと継承クラスならアクセス可

    constructor(name: string) {

        this.name = name;

    }

    public message(): string {

        return `こんにちは、${this.name} さん!`;

    }

}

まずはUserクラスですが1ヵ所だけ変更しておく部分があります。
それは変数nameのアクセス・スコープです。

先ほどはprivateでしたが、今回はアクセス範囲をprotectedにします。
これで、継承された先のクラスAdminからでもアクセスできるようになります。

【2.Adminクラス】

では、Userを拡張したAdminクラスです。

class Admin extends User { // 👈 継承を指定

    private age: number = -1;

    constructor(name: string) {

        super(name);

    }

    public setAge(age: number): void {

        this.age = age;

    }

    public message(): string { // 👈 内容を上書き

        return `こんにちは、${this.name}(${this.age}歳) さん!`;

    }

}

この中で重要なのは、extends Userでクラスを継承している部分です。

また、Adminだけに必要なsetAge()を追加し、すでに存在している同名のメソッドmessage()をあえて設置して内容を上書きしています。

実際の使い方はこうなります。

const admin = new Admin('山田太郎');
admin.setAge(25);

console.log(
    admin.message() // 「こんにちは、山田太郎(25歳) さん!」
);
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はTypeScriptの関数、インターフェイス、クラスの使い方をご紹介しました。

なお、これはTypeScriptだけではないですがプログラムは1つの言語をマスターしておけば、他のものでも「標準語と関西弁」ぐらいの違いなので、根本は同じなんだな、と感じています。

というのも、今回のクラスで使ったアクセス・スコープPHPにもありますし、関数の型宣言はJavaそっくりですよね。

そのため、プログラミング学習者の方々は暗記というよりは根本的な構造を意識しながら勉強していくと後々楽ができると思います。

ぜひ、そんな感じでチャレンジしてみてくださいね。

ではでは〜❗

「コロナの影響で外出を自粛中。
クラフトビールが飲みに行けない😓
・・・今はガマン❗」

このエントリーをはてなブックマークに追加       follow us in feedly