TL;DR
このページでは、TypeScript の "型エイリアス(type alias)" の実装方法について解説しますね。一言でいうと、型エイリアスとは、既存の型にtype
キーワードを使用して新しい名前を付け、同じ型を複数回利用させる機能のことです。
開発環境 | バージョン |
---|---|
Next.js | 13.4.4 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
型エイリアスとは?
型エイリアス(Type Alias)は、TypeScript の重要な特性の一つです。これを理解し、上手く使うことで、コードの可読性や再利用性を向上させ、エラーの可能性を低減することができます。
型エイリアスを理解するための一つの基本的な考え方は、「既存の型に新しい名前を付ける」というものです。それを使うことで、コード全体を通じて型を一貫して使用することができます。
type Name = string
let name: Name
name = 'John Doe' // これは正しい
name = 123 // これはエラー
上記のコードでは、"Name"という新しい型エイリアスを定義しています。そして、それを使って"name"という変数を宣言しています。この"name"変数は"Name"という型を持っているため、"string"型の値を受け入れます。だから、name 変数に文字列を代入するときはエラーにならないのです。しかし、number 型の値を代入しようとすると、TypeScript はエラーを出します。
プリミティブ型
プリミティブ型に対する型エイリアスです。文字列や数値、真偽値などの基本的なデータ型に対して新しい名前を定義します。
type ID = string
type Age = number
type IsAdult = boolean
let id: ID = '1234'
let age: Age = 25
let isAdult: IsAdult = true
ここで定義した ID
, Age
, IsAdult
はそれぞれ string
, number
, boolean
の別名として扱われます。
ユニオン型
ユニオン型は複数の型のいずれかを表すことができます。ユニオン型の型エイリアスを定義することで、特定の範囲の値のみを許容する型を作ることができます。
type Animal = 'Dog' | 'Cat' | 'Bird'
let pet: Animal
pet = 'Dog' // これは正しい
pet = 'Fish' // これはエラー
この例では Animal
という型エイリアスは 'Dog'
, 'Cat'
, 'Bird'
のいずれかの文字列しか許容しません。
インターセクション型
インターセクション型は複数の型を組み合わせた新しい型を作ることができます。既存の型エイリアスを組み合わせて新しい型エイリアスを作ることができます。
type User = {
name: string
age: number
}
type Worker = {
company: string
}
type UserWorker = User & Worker
let userWorker: UserWorker = {
name: 'John Doe',
age: 25,
company: 'Tech Corp',
} // これは正しい
ここでは User
と Worker
という 2 つの型エイリアスを組み合わせて UserWorker
という新しい型エイリアスを作成しています。
タプル
タプルは固定数の要素と各要素の型が指定された配列の型を定義することができます。タプルを表すための型エイリアスを定義することができます。
type Point = [number, number]
let p: Point = [10, 20] // これは正しい
ここで定義した Point
は 2 つの数値からなる配列を表します。
関数型(アロー関数)
関数型の型エイリアスでは、特定の形式の関数を定義することができます。パラメータと戻り値の型を指定します。
type Greeting = (name: string) => string
const hello: Greeting = (name) => `Hello, ${name}`
console.log(hello('World')) // Hello, World
この例では、Greeting
という型エイリアスは string
を引数に取り string
を返す関数を表します。
ジェネリクス
ジェネリクスは特定の型に依存せずに再利用可能なコードを作るための機能です。型エイリアスでジェネリクスを定義することも可能です。
type Container<T> = { value: T }
let numberContainer: Container<number> = { value: 1 }
let stringContainer: Container<string> = { value: 'Hello World' }
この例では Container<T>
というジェネリクス型の型エイリアスを作成しています。T
は任意の型を表すプレースホルダーで、具体的な型は使用する際に指定します。
アロー関数とジェネリック型の組み合わせ
アロー関数とジェネリック型を組み合わせて利用することで、より汎用性の高いコードを書くことができます。
// ファイル名: components/Identity.tsx
type IdentityFunction<T> = (arg: T) => T
const identity: IdentityFunction<number> = (arg) => {
return arg
}
// 使用例
const result = identity(123)
console.log(result) // 123
このコードでは、IdentityFunction
という型エイリアスを定義しています。その中でジェネリック型<T>
を使って、引数と戻り値の型が同一であるような関数を表現しています。このT
は、関数を実際に使用する際に具体的な型(この場合はnumber
)に置き換わります。
このようなジェネリック型を使うことで、多様な型に対応する関数を一つの型定義で表現することができます。この例ではnumber
型に対するIdentityFunction
を定義していますが、string
型や自作の型など、様々な型に対して同じ関数を適用できます。
ネストした型エイリアス
複雑なデータ構造を表現するために、型エイリアスをネストして使用することもあります。
type User = {
id: string
profile: {
name: string
age: number
}
}
let user: User = {
id: '1234',
profile: {
name: 'John Doe',
age: 25,
},
}
この例では User
という型エイリアス内部に profile
という別のオブジェクトの型を定義しています。
Next.js で、型エイリアスを実装
基本的な型エイリアスの使い方を理解したところで、それを具体的な Next.js プロジェクトでの使用例を見ていきましょう。この部分では、「UserCard」というコンポーネントとその呼び出し方法を示します。
先ずは、components/UserCard.tsx
ファイルを作成します。
// components/UserCard.tsx
import React from 'react'
type User = {
name: string
age: number
address: string
}
const UserCard = ({ name, age, address }: User) => {
return (
<div>
<h2>{name}</h2>
<p>{age}歳</p>
<p>{address}</p>
</div>
)
}
export default UserCard
上記のコードでは、まず最初に"User"という型エイリアスを定義しています。この"User"型は、"name"、"age"、"address"というプロパティを持つオブジェクトを表しています。それぞれのプロパティは、"string"、"number"、"string"という型を持っています。
次に、"UserCard"という React コンポーネントを定義しています。このコンポーネントは、User 型のプロパティを引数として受け取ります。そして、それらのプロパティを使用して、ユーザーの情報を表示します。
// pages/index.tsx
import UserCard from '../components/UserCard'
const Home = () => {
return (
<div>
<UserCard name="John Doe" age={30} address="Tokyo, Japan" />
</div>
)
}
export default Home
上記のコードでは、UserCard コンポーネントを呼び出しています。それぞれのプロパティに適切な値を渡しています。これにより、Next.js アプリケーションでユーザーの情報を表示することができます。
型エイリアスの拡張
型エイリアスは、より複雑な型を作成するためにも使用することができます。たとえば、既存の型エイリアスを合成して、新たな型エイリアスを作成することができます。
以下の例では、「AdminUser」型エイリアスを作成します。これは既存の「User」型エイリアスを拡張し、新たなプロパティ「role」を追加します。
// components/AdminUserCard.tsx
import React from 'react'
type User = {
name: string
age: number
address: string
}
type AdminUser = User & {
role: string
}
const AdminUserCard = ({ name, age, address, role }: AdminUser) => {
return (
<div>
<h2>{name}</h2>
<p>{age}歳</p>
<p>{address}</p>
<p>Role: {role}</p>
</div>
)
}
export default AdminUserCard