【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. 参考

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

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

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

  3. TypeScript

    【TypeScript】Vitestを使ってみる

  4. TypeScript

    【TypeScript】ループ時の非同期処理の処理順序(async/a…

  5. Firebase

    【Firebase】Firestore Security Rulesを…

  6. TypeScript

    【TypeScript】触ってみる

最近の記事

  1. flutter

制作実績一覧

  1. Checkeys