extendsとimplementsを使いこなして、TypeScriptコードをレベルアップ!

2024-04-02

TypeScriptにおけるextendsとimplementsの違い

extends

extendsは、クラス継承に使用されます。あるクラスが別のクラスのプロパティメソッドを受け継ぐことを可能にします。

例:

class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

class Dog extends Animal {
  bark() {
    console.log('Woof!');
  }
}

const dog = new Dog('Rex');
console.log(dog.name); // 'Rex'
dog.bark(); // 'Woof!'

上記の例では、DogクラスはAnimalクラスをextendsしています。そのため、Dogクラスはnameプロパティとconstructorメソッドを自動的に受け継ぎます。さらに、Dogクラスは独自のbark()メソッドを追加しています。

implements

implementsは、インターフェースの実装に使用されます。あるクラスがインターフェースで定義されたプロパティメソッドを実装することを約束します。

interface Person {
  name: string;
  age: number;
  greet(): string;
}

class Employee implements Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  greet(): string {
    return `Hello, my name is ${this.name}`;
  }
}

const employee = new Employee('John Doe', 30);
console.log(employee.name); // 'John Doe'
console.log(employee.age); // 30
console.log(employee.greet()); // 'Hello, my name is John Doe'

上記の例では、EmployeeクラスはPersonインターフェースをimplementsしています。そのため、Employeeクラスはnameプロパティ、ageプロパティ、greet()メソッドを実装する必要があります。

  • extendsはクラス継承に使用し、プロパティとメソッドを受け継ぐ。
  • implementsはインターフェースの実装に使用し、プロパティとメソッドを実装する。

ポイント

  • クラスはextendsキーワードを使って1つのクラスのみを継承できる。
  • クラスはimplementsキーワードを使って複数のインターフェースを実装できる。
  • インターフェースはextendsキーワードを使用できない。

これらの違いを理解することで、TypeScriptにおけるコードの構造と意味をより明確に理解することができます。




クラス継承

class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  speak() {
    console.log(`I am an animal. My name is ${this.name}`);
  }
}

class Dog extends Animal {
  bark() {
    console.log('Woof!');
  }
}

const dog = new Dog('Rex');
dog.speak(); // 'I am an animal. My name is Rex'
dog.bark(); // 'Woof!'
  • Animalクラスは、nameプロパティとconstructorメソッド、speak()メソッドを持つ基底クラスです。
  • DogクラスはAnimalクラスをextendsし、bark()メソッドを追加しています。
  • dogオブジェクトはDogクラスのインスタンスであり、nameプロパティ、constructorメソッド、speak()メソッド、bark()メソッドを持つことができます。

インターフェースの実装

interface Person {
  name: string;
  age: number;
  greet(): string;
}

class Employee implements Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  greet(): string {
    return `Hello, my name is ${this.name}`;
  }
}

const employee = new Employee('John Doe', 30);
console.log(employee.name); // 'John Doe'
console.log(employee.age); // 30
console.log(employee.greet()); // 'Hello, my name is John Doe'

解説:

  • Personインターフェースは、nameプロパティ、ageプロパティ、greet()メソッドを持つ型を定義します。
  • employeeオブジェクトはEmployeeクラスのインスタンスであり、nameプロパティ、ageプロパティ、greet()メソッドを持つことができます。

複数のインターフェースの実装

interface Animal {
  name: string;
  speak(): string;
}

interface Person {
  age: number;
  greet(): string;
}

class Employee implements Animal, Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  speak(): string {
    return `I am an animal. My name is ${this.name}`;
  }
  greet(): string {
    return `Hello, my name is ${this.name}`;
  }
}

const employee = new Employee('John Doe', 30);
console.log(employee.name); // 'John Doe'
console.log(employee.age); // 30
console.log(employee.speak()); // 'I am an animal. My name is John Doe'
console.log(employee.greet()); // 'Hello, my name is John Doe'
  • EmployeeクラスはAnimalインターフェースとPersonインターフェースをimplementsし、両方のインターフェースで定義されたプロパティとメソッドを実装しています。

これらのサンプルコードは、extendsimplementsキーワードの使用方法をより深く理解するのに役立ちます。




extends と implements のその他の使用方法

extends キーワードを使用して抽象クラスを継承することができます。抽象クラスは、子クラスが実装しなければならない抽象メソッドを持つクラスです。

abstract class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  abstract speak(): string;
}

class Dog extends Animal {
  bark() {
    console.log('Woof!');
  }
  speak(): string {
    return `I am a dog. My name is ${this.name}`;
  }
}

const dog = new Dog('Rex');
dog.speak(); // 'I am a dog. My name is Rex'
  • Animalクラスは抽象クラスであり、抽象メソッドspeak()を持っています。

ジェネリック型

extends キーワードを使用してジェネリック型を継承することができます。ジェネリック型は、型パラメータを使用して異なる型を受け入れることができる型です。

interface Container<T> {
  item: T;
}

class Box<T> implements Container<T> {
  item: T;
  constructor(item: T) {
    this.item = item;
  }
}

const box = new Box('Hello, world!');
console.log(box.item); // 'Hello, world!'
  • Containerインターフェースはジェネリック型であり、型パラメータTを受け入れます。

ミックスイン

implements キーワードを使用してミックスインを実装することができます。ミックスインは、複数のクラスに共通する機能を提供するオブジェクトです。

interface Logger {
  log(message: string): void;
}

class MyClass implements Logger {
  log(message: string): void {
    console.log(message);
  }
}

const myClass = new MyClass();
myClass.log('Hello, world!'); // 'Hello, world!'
  • Loggerインターフェースは、log()メソッドを持つオブジェクトを表します。
  • MyClassクラスはLoggerインターフェースをimplementsし、log()メソッドを実装しています。

extendsimplements キーワードには、上記以外にもさまざまな使用方法があります。これらのキーワードを使いこなすことで、より柔軟で再利用可能なコードを書くことができます。


typescript extends implements


HTML、Angular、TypeScriptにおける「Cannot approach Typescript enum within HTML」エラーの解決策

原因:HTMLはJavaScriptとは異なる言語であり、TypeScriptの列挙型を直接理解できません。そのため、HTMLテンプレート内で列挙型の値を参照しようとすると、エラーが発生します。解決策:このエラーを解決するには、以下のいずれかの方法を使用できます。...


RxJSパイプ徹底解説! 〜Angular・TypeScript開発で役立つデータ変換・処理のテクニック〜

パイプの役割パイプは、以下の役割を果たします。データの変換: Observableの値を変換したり、フォーマットしたりすることができます。処理の追加: Observableにフィルタリング、マッピング、エラー処理などの処理を追加することができます。...


「Error: Schema validation failed」: Angular/TypeScript移行における問題点と解決策

このエラーを解決するには、以下の手順に従ってください。追加プロパティを特定する:エラーメッセージには、問題のあるプロパティ名が表示されていないことに注意してください。特定するには、以下のツールを使用できます。Visual Studio Code: エラーメッセージにマウスカーソルを合わせると、問題のあるプロパティに関する情報が表示されます。...


as キーワードを使いこなして TypeScript コードをレベルアップ

型ガードas キーワードは、変数の型が特定の型であるかどうかを確認するために使用できます。これは、条件付きステートメントや関数呼び出しで使用されます。例:この例では、value 変数の型は any です。as キーワードを使用して、value が string 型かどうかを確認しています。...


【TypeScript初心者向け】Jest & Cypressで型エラーが発生した時の解決策

TypeScript、Jest、Cypress を組み合わせた開発環境において、「Cypress が Jest のアサーションで型エラーを引き起こす」という問題が発生することがあります。これは、各ライブラリ間の型システムの不一致が原因で起こります。...


SQL SQL SQL SQL Amazon で見る



TypeScriptの継承と実装の奥深さ:抽象クラスとインターフェースで探求する高度な設計

継承 (extends) と 実装 は、抽象クラスとサブクラスの関係性を定義する2つの主要な概念です。継承 は、サブクラスが抽象クラスの構造と機能を継承することを意味します。具体的には、サブクラスは抽象クラスの:プロパティ: データを保持する変数