TypeScriptでオブジェクトの構造を詳細に定義: インターフェースと型ガードを活用
TypeScriptインターフェース: オブジェクトの既知と未知のプロパティ
既知のプロパティ
オブジェクトに既知のプロパティがある場合、インターフェースでそれらのプロパティを定義できます。たとえば、次のインターフェースは、firstName
と lastName
というプロパティを持つオブジェクトを定義します。
interface Person {
firstName: string;
lastName: string;
}
このインターフェースを使用して、次のようにオブジェクトを作成できます。
const person: Person = {
firstName: "John",
lastName: "Doe"
};
person
変数は Person
インターフェース型のオブジェクトであるため、firstName
と lastName
プロパティにアクセスできます。
オブジェクトに未知のプロパティがある場合、[x: string]: any
という構文を使用して、それらのプロパティを定義できます。この構文は、オブジェクトのプロパティ名が文字列である限り、任意の型のプロパティを許可します。
たとえば、次のインターフェースは、firstName
と lastName
という既知のプロパティに加えて、任意の数の未知のプロパティを持つオブジェクトを定義します。
interface PersonWithExtras extends Person {
[x: string]: any;
}
const personWithExtras: PersonWithExtras = {
firstName: "John",
lastName: "Doe",
age: 30,
occupation: "Software Engineer"
};
personWithExtras
変数は PersonWithExtras
インターフェース型のオブジェクトであるため、firstName
、lastName
、age
、occupation
プロパティにアクセスできます。
TypeScriptインターフェースは、オブジェクトの構造を定義するために使用できます。インターフェースには、オブジェクトが持つ必要があるプロパティと、それぞれのプロパティの型を指定できます。既知のプロパティに加えて、未知のプロパティを定義することもできます。
例
次の例は、Person
インターフェースを使用して、オブジェクトを作成し、そのプロパティにアクセスする方法を示しています。
interface Person {
firstName: string;
lastName: string;
}
const person: Person = {
firstName: "John",
lastName: "Doe"
};
console.log(person.firstName); // "John"
console.log(person.lastName); // "Doe"
この例では、Person
インターフェースを使用して、person
という名前のオブジェクトを作成します。person
オブジェクトには、firstName
と lastName
という 2 つのプロパティがあります。次に、console.log()
関数を使用して、firstName
と lastName
プロパティの値を出力します。
interface PersonWithExtras extends Person {
[x: string]: any;
}
const personWithExtras: PersonWithExtras = {
firstName: "John",
lastName: "Doe",
age: 30,
occupation: "Software Engineer"
};
console.log(personWithExtras.firstName); // "John"
console.log(personWithExtras.lastName); // "Doe"
console.log(personWithExtras.age); // 30
console.log(personWithExtras.occupation); // "Software Engineer"
サンプル1: 既知のプロパティ
interface Person {
firstName: string;
lastName: string;
}
const person: Person = {
firstName: "John",
lastName: "Doe"
};
console.log(person.firstName); // "John"
console.log(person.lastName); // "Doe"
説明
interface Person
で、Person
という名前のインターフェースを定義します。firstName: string;
とlastName: string;
で、Person
インターフェースが持つプロパティを定義します。firstName
とlastName
はどちらも文字列型 (string) です。const person: Person = { firstName: "John", lastName: "Doe" };
で、person
という名前の変数にPerson
インターフェース型のオブジェクトを作成します。firstName
に "John"、lastName
に "Doe" を代入しています。console.log(person.firstName);
とconsole.log(person.lastName);
で、person
オブジェクトのfirstName
とlastName
プロパティの値を出力します。
interface PersonWithExtras extends Person {
[x: string]: any;
}
const personWithExtras: PersonWithExtras = {
firstName: "John",
lastName: "Doe",
age: 30,
occupation: "Software Engineer"
};
console.log(personWithExtras.firstName); // "John"
console.log(personWithExtras.lastName); // "Doe"
console.log(personWithExtras.age); // 30
console.log(personWithExtras.occupation); // "Software Engineer"
interface PersonWithExtras extends Person
で、PersonWithExtras
という名前のインターフェースを定義します。PersonWithExtras
はPerson
インターフェースを継承します。[x: string]: any;
で、PersonWithExtras
インターフェースが持つ未知のプロパティを定義します。x
は文字列型 (string) で、その値は任意の型 (any) です。const personWithExtras: PersonWithExtras = { firstName: "John", lastName: "Doe", age: 30, occupation: "Software Engineer" };
で、personWithExtras
という名前の変数にPersonWithExtras
インターフェース型のオブジェクトを作成します。firstName
に "John"、lastName
に "Doe"、age
に 30、occupation
に "Software Engineer" を代入しています。console.log(personWithExtras.firstName);
、console.log(personWithExtras.lastName);
、console.log(personWithExtras.age);
、console.log(personWithExtras.occupation);
で、personWithExtras
オブジェクトのfirstName
、lastName
、age
、occupation
プロパティの値を出力します。
- インターフェースの合併
インターフェースは合併できます。これは、複数のインターフェースのプロパティを 1 つのインターフェースに組み合わせることを意味します。 - ジェネリック型
インターフェースはジェネリック型を使用して、パラメーター化できます。これは、インターフェースのプロパティの型が実行時に決定されることを意味します。 - インターフェースの継承
インターフェースは継承できます。これは、あるインターフェースが別のインターフェースのすべてのプロパティとメソッドを継承することを意味します。
型ガード
interface Person {
firstName: string;
lastName: string;
}
const person: Person = {
firstName: "John",
lastName: "Doe"
};
if (typeof person.age === "number") {
console.log(person.age); // 型ガードが成功した場合のみ実行
} else {
console.error("`person.age` は数字ではありません");
}
if (typeof person.age === "number")
で、person.age
が数字型 (number) であるかどうかを確認します。typeof person.age === "number"
がtrue
の場合、console.log(person.age);
でperson.age
の値を出力します。typeof person.age === "number"
がfalse
の場合、console.error("
person.ageは数字ではありません");
でエラーメッセージを出力します。
型アサーション
型アサーションを使用して、オブジェクトのプロパティに特定の型を明示的に割り当てることができます。これにより、コンパイラにオブジェクトのプロパティの型を伝えることができ、より詳細な型チェックが可能になります。
interface Person {
firstName: string;
lastName: string;
}
const person: Person = {
firstName: "John",
lastName: "Doe"
};
const age = person.age as number; // 型アサーション
if (typeof age === "number") {
console.log(age);
} else {
console.error("`age` は数字ではありません");
}
const age = person.age as number;
で、person.age
に数字型 (number) を明示的に割り当てます。
オプションプロパティ
オプションプロパティを使用して、オブジェクトのプロパティが必須かどうかを指定できます。
interface Person {
firstName: string;
lastName: string;
age?: number; // オプションプロパティ
}
const person: Person = {
firstName: "John",
lastName: "Doe"
};
console.log(person.age); // undefined
const personWithAge: Person = {
firstName: "Jane",
lastName: "Doe",
age: 30
};
console.log(personWithAge.age); // 30
age?: number;
で、age
プロパティをオプションプロパティとして定義します。これは、age
プロパティが必須ではないことを意味します。const personWithAge: Person = { firstName: "Jane", lastName: "Doe", age: 30 };
で、personWithAge
という名前の変数にPerson
インターフェース型のオブジェクトを作成します。age
プロパティに 30 を代入します。console.log(person.age);
で、person
オブジェクトのage
プロパティの値を出力します。age
プロパティは存在しないため、undefined
を出力します。
typescript