Interface
オブジェクトの構造を表したものです。
Interfaceはオブジェクトのみ、Type aliasは全部いけます。
interface Human {
name: string;
age: number;
}
const human: Human = {
name: 'Quill',
age: 38
}
Interfaceにメソッドを追加する
方法1
↓関数を型注釈する方法
interface Human {
name: string;
age: number;
greeting: (message: string) => void;
}
↓方法2
interface Human {
name: string;
age: number;
greeting(message: string): void;
}
classにInterfaceの条件を適用させる
implements = 実装
↓で、Humanの条件を満たすようなDeveloperを作るといったような解釈になります。
interface Human {
name: string;
age: number;
greeting(message: string): void;
}
class Developer implements Human{
}
↓また、implementsは複数付けることができます。
class Developer implements Human, Job, Hobby{
}
構造的部分型
↓最後の行では、Humanの{name, age, greeting}が入っていさえすればOKになります。
↓なのでnew Developerの引数にexperienceの値が入っていても問題ありません。
interface Human {
name: string;
age: number;
greeting(message: string): void;
}
class Developer implements Human{
constructor(public name: string, public age: number, public experience: number) {}
greeting(message: string) {
console.log('Hello');
}
}
const user: Human = new Developer('Quill', 38, 3);
↓わかりやすいようにtmpDeveloperを定義して書いてみても、これもOKです。
interface Human {
name: string;
age: number;
greeting(message: string): void;
}
class Developer implements Human{
constructor(public name: string, public age: number, public experience: number) {}
greeting(message: string) {
console.log(message);
}
}
const tmpDeveloper = {
name: 'Quill',
age: 38,
experience: 3,
greeting(message: string) {
console.log(message);
}
}
const user: Human = tmpDeveloper;
これらの何が良いかというと、パッとみただけで、
userは「少なくともHumanの中身の要素は持っているんだ」と分かることです。
interfaceにreadonly修飾子を付ける
↓classと同じように付けることができます。
↓interfaceのnameにreadonlyを付けても、implementsのnameには影響を及ぼしません。
interface Human {
readonly name: string;
age: number;
greeting(message: string): void;
}
class Developer implements Human{
constructor(public name: string, public age: number, public experience: number) {}
greeting(message: string) {
console.log(message);
}
}
interfaceを継承する
classと同じようにextendsを使います。
↓interface Humanにinterface Nameableを継承しています。
interface Nameable {
name: string;
}
interface Human extends Nameable {
name: string;
age: number;
greeting(message: string): void;
}
class Developer implements Human{
constructor(public name: string, public age: number, public experience: number) {}
greeting(message: string) {
console.log(message);
}
}
interface Nameableのnameの型に、interface Humanの型が代入できる限り、
Humanの方の型は何度でも代入できます。
interfaceで関数の型を表現する
↓メソッド名を書きません。
↓addFuncは、関数の型を定義したことと同じになります。
↓addFuncは、引数としてnumberを2つ持って、numberを戻り値として返します。
interface addFunc {
(num1: number, num2: number): number;
}
?を使ってあってもなくても良い処理を実装する
?は、プロパティの前に付けることができます。
↓nickNameは、あってもなくてもエラーになりません。
type Nameable = {
name: string;
nickName?: string;
}
const nameable: Nameable = {
name: 'Quill'
}
↓パラメーターにも付けることができます。
greeting(message?: string) {
console.log(message);
}
↓fieldにも付けることができます。
name?: string;