【TypeScript】インターフェイスの実装

TypeScript

1. 概要

こちらのTypeScriptのTutorialを、コード中心に書いていきます。

  • オブジェクト指向プログラミングの場合と同様にインターフェイスを使用できる。
  • インターフェイスを使用してオブジェクトの型を定義することもできる。
  • TypeScriptとコンパイルされたJavaScriptを見比べながら見て下さい。

2. TypeScriptのコンパイラをインストール

2-1. こちらを参考

3. tsconfig.json を生成 + 修正

3-1. こちらを参考

4. コードを書いて確認

4-1. サンプルコード1

  • module03-1.ts
interface Employee {
    firstName: string;
    lastName: string;
    fullName(): string;
}

let employee: Employee = {
    firstName: 'Emil',
    lastName: 'Andersson',
    fullName(): string {
        return this.firstName + ' ' + this.lastName;
    },
}

// employee.firstName = 10; // NG : Type 'number' is not assignable to type 'string'.
employee.firstName = 'Aurora'; // OK

console.log(employee.fullName());

type EmployeeType = {
    firstName: string;
    lastName: string;
    fullName(): string;
}

let employeeType: EmployeeType = {
    firstName: 'Emil',
    lastName: 'Andersson',
    fullName(): string {
        return this.firstName + ' ' + this.lastName;
    },
}

// employeeType.firstName = 10; // NG : Type 'number' is not assignable to type 'string'.
employeeType.firstName = 'White'; // OK

console.log(employeeType.fullName());
  • コンパイル
    • tsv
  • build/module03-1.js
"use strict";
let employee = {
    firstName: 'Emil',
    lastName: 'Andersson',
    fullName() {
        return this.firstName + ' ' + this.lastName;
    },
};
// employee.firstName = 10; // NG : Type 'number' is not assignable to type 'string'.
employee.firstName = 'Aurora'; // OK
console.log(employee.fullName());
let employeeType = {
    firstName: 'Emil',
    lastName: 'Andersson',
    fullName() {
        return this.firstName + ' ' + this.lastName;
    },
};
// employeeType.firstName = 10; // NG : Type 'number' is not assignable to type 'string'.
employeeType.firstName = 'White'; // OK
console.log(employeeType.fullName());
  • 実行
    • node build/module03-1.js
  • 実行結果
Aurora Andersson
White Andersson

4-2. サンプルコード2

  • module03-2.ts
interface IceCream {
    flavor: string;
    scoops: number;
    instructions?: string;
}
let myIceCream: IceCream = {
    flavor: 'vanilla',
    scoops: 2
}
console.log(myIceCream.flavor);

const tooManyScoops = (dessert: IceCream) => {
    if (dessert.scoops >= 4) {
        return dessert.scoops + ' is too many scoops!';
    } else {
        return 'Your order will be ready soon!';
    }
}
console.log(tooManyScoops({flavor: 'vanilla', scoops: 5}));
  • コンパイル
    • tsv
  • build/module03-2.js
"use strict";
let myIceCream = {
    flavor: 'vanilla',
    scoops: 2
};
console.log(myIceCream.flavor);
const tooManyScoops = (dessert) => {
    if (dessert.scoops >= 4) {
        return dessert.scoops + ' is too many scoops!';
    }
    else {
        return 'Your order will be ready soon!';
    }
};
console.log(tooManyScoops({ flavor: 'vanilla', scoops: 5 }));
  • 実行
    • node build/module03-2.js
  • 実行結果
vanilla
5 is too many scoops!

4-3. サンプルコード3

  • module03-3.ts
interface Sundae extends IceCream {
    sauce: 'chocolate' | 'caramel' | 'strawberry';
    nuts?: boolean;
    whippedCream?: boolean;
    // instructions?: boolean; //親と型が異なるとエラー
    instructions?: string;
}

let myIceCream1: Sundae = {
    flavor: 'vanulla',
    scoops: 2,
    sauce: 'caramel',
    nuts: true
}

const tooManyScoops1 = (dessert: Sundae) => {
    if (dessert.scoops >= 4) {
        return dessert.scoops + ' is too many scoops!';
    } else {
        return 'Your order will be ready soon!';
    }
}
console.log(tooManyScoops1({flavor: 'vanilla', scoops: 5, sauce: 'caramel'}));
  • コンパイル
    • tsv
  • build/module03-3.js
"use strict";
let myIceCream1 = {
    flavor: 'vanulla',
    scoops: 2,
    sauce: 'caramel',
    nuts: true
};
const tooManyScoops1 = (dessert) => {
    if (dessert.scoops >= 4) {
        return dessert.scoops + ' is too many scoops!';
    }
    else {
        return 'Your order will be ready soon!';
    }
};
console.log(tooManyScoops1({ flavor: 'vanilla', scoops: 5, sauce: 'caramel' }));
  • 実行
    • node build/module03-3.js
  • 実行結果
5 is too many scoops!

4-4. サンプルコード4

  • module03-4.ts
// インデックスを付けることが可能な型を作成する
interface IceCreamArray {
    [idx: number]: string;
}
let myIceCream2: IceCreamArray;
myIceCream2 = ['chocolate', 'vanilla', 'strawberry'];
let myStr: string = myIceCream2[0];
console.log(myStr);

// インターフェイスを使用して JavaScript API を記述する
const fetchURL = 'https://jsonplaceholder.typicode.com/posts';
interface Post {
    userId: number;
    id: number;
    title: string;
    body: string;
}
const fetchPosts = async (url: string) => {
    let response = await fetch(url);
    let body = await response.json();
    return body as Post[];
}
const showPost = async () => {
    let posts = await fetchPosts(fetchURL);
    let post = posts[0];
    console.log(`Post #${post.id}`);
    console.log(`Author: ${post.userId === 1 ? 'Administrator' : post.userId.toString()}`);
    console.log(`Title: ${post.title}`);
    console.log(`Body: ${post.body}`);
}
showPost();
  • コンパイル
    • tsv
  • build/module03-4.js
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
let myIceCream2;
myIceCream2 = ['chocolate', 'vanilla', 'strawberry'];
let myStr = myIceCream2[0];
console.log(myStr);
// インターフェイスを使用して JavaScript API を記述する
const fetchURL = 'https://jsonplaceholder.typicode.com/posts';
const fetchPosts = (url) => __awaiter(void 0, void 0, void 0, function* () {
    let response = yield fetch(url);
    let body = yield response.json();
    return body;
});
const showPost = () => __awaiter(void 0, void 0, void 0, function* () {
    let posts = yield fetchPosts(fetchURL);
    let post = posts[0];
    console.log(`Post #${post.id}`);
    console.log(`Author: ${post.userId === 1 ? 'Administrator' : post.userId.toString()}`);
    console.log(`Title: ${post.title}`);
    console.log(`Body: ${post.body}`);
});
showPost();
  • 実行
    • node build/module03-4.js
  • 実行結果
chocolate
Post #1
Author: Administrator
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto

ディレクトリ構成

tree
.
├── build
│   ├── module03-1.js
│   ├── module03-2.js
│   ├── module03-3.js
│   └── module03-4.js
├── module03-1.ts
├── module03-2.ts
├── module03-3.ts
├── module03-4.ts
└── tsconfig.json

1 directory, 9 files

5. プロパティの種類

  • 必須
    • firstName: string;
  • 省略可能
    • firstName?: string;
  • 読み取り専用
    • readonly firstName: string;

6. 備考

インターフェイスを使用してオブジェクトの型を定義すると、何を意図しているのかわかりやすくなりますね。

7. 参考

関連記事

  1. TypeScript

    【TypeScript】TypeScriptで変数の型を宣言する

  2. 【TypeScript】filterを使って配列からundefined…

  3. TypeScript

    【TypeScript】Vitestを使ってみる

  4. 【React】FullCalendarを使用してカレンダーを表示するた…

  5. Firebase

    【Firebase】Firestore Security Rulesを…

  6. 【React】FullCalendarのカレンダーにイベントを表示する…

最近の記事

  1. AWS
  2. AWS
  3. AWS
  4. AWS
  5. AWS
  6. AWS
  7. AWS

制作実績一覧

  1. Checkeys