【TypeScript】Partial<T>とは、使うと何がいい？

# はじめに
TypeScriptの学習を進めていて、`Partial<T>`という型があることを学びました。
`Partial<T>`の概要と、使用メリットについて学んだことをまとめます。

# Partial\<T>とは
**サバイバルTypeScriptより引用**
>Partial\<T>は、オブジェクトの型Tのすべてのプロパティをオプションプロパティにするユーティリティ型です。
>>ユーティリティ型 (utility type)は、型から別の型を導き出してくれる型です。

# Partial\<T>の基本的な使い方
例えば、以下のtypeを定義していたとします。

```ts:type.ts
export type Data = {
  id: string;
  title: string;
  time: number;
  created_at: string;
};

const data: Data = {
  id: "1",
  title: "タイトル",
  time: 1,
  created_at: "2025-04-06",
};

console.log(data);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/79f7dc78-b8db-4e5e-8631-9ad5710f2d02.png)

この場合、全てのプロパティを指定しないとコンパイルエラーになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/40b190e2-73c4-4615-8cad-07fcbbf37f1f.png)

`export type Data = {}`の各プロパティを全てオプションにしたいとき、各プロパティに`?`をつけることで可能です。
しかし、仮にプロパティが何10個もあるようなデータ型だと、全てに`?`をつけるのは大変です。

その時に`Partial`を使用すると簡潔に各プロパティをオプションにすることができます。
```ts:type.ts
export type Data = {
  id: string;
  title: string;
  time: number;
  created_at: string;
};

// 既存のDataのプロパティを全てオプションにする
export type newData = Partial<Data>;
```

この結果、内部的にnewDataは次のように変換されます。
```ts
export type newData = {
  id?: string | undefined;
  title?: string | undefined;
  time?: number | undefined;
  created_at?: string | undefined;
};
```

```ts
// timeプロパティのみ指定
const newData: newData = {
  time: 1,
};
console.log(newData);
```
timeプロパティのみ指定した実行結果は下記のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/e157bc04-0a40-47d4-9f84-00d3a3c2d6f1.png)



# Partial\<T>の使いどころ
主な使用例は下記の通りです。各使用例とメリットについてまとめました。
1. オブジェクトの一部だけを更新したいとき
2. フォーム入力の状態管理
2. テストデータの作成


### 1.オブジェクトの一部だけを更新したいとき
#### データの一部だけを更新したいときに使用
例として、ユーザー情報の名前だけ変更したい場合を考えてみます
本来はユーザー情報全てのプロパティを指定しないといけない所、`Partial<T>`を使うことで名前だけ更新することができます。

```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

// ❌ Partialなしの場合（すべてのプロパティが必要）
const updateUserWithoutPartial = (user: User) => {
  // 更新処理
};

// このように呼び出す必要がある（すべてのプロパティを指定）
updateUserWithoutPartial({
  id: 1,
  name: "なまえ",
  email: "name@example.com",
  age: 20
});

// ✅ Partialを使った場合（一部のプロパティだけでOK）
const updateUser = (userId: number, updates: Partial<User>) => {
  // userIdで既存データを取得、updatesの内容で更新
};

// 名前だけ更新で済む
updateUser(1, { name: "田中あああ" });
```

### 2.フォーム状態の管理
#### 不完全な状態や任意の項目のときに使用
例として、入力途中のデータを保存したいときを考えてみます。
`Partial<T>`を使用しない場合、登録項目をすべて指定しないと、登録できません。
名前だけを途中で保存したいとき、`Partial<T>`を使うことで名前だけ登録することができます。

```ts
// ユーザー情報の型
type UserForm = {
  name: string;
  email: string;
  age: number;
  address: string;
};

// ❌ Partialなしの場合（すべてのプロパティが必要）
// ユーザー登録関数
function registerUser(user: UserForm) {
  // ユーザー登録処理
  console.log("ユーザーを登録しました:", user);
}

// 使用例（全ての情報が必要）
registerUser({
  name: "山田あああ",
  email: "",   //名前のみ登録したい場合、空文字を指定する必要がある
  age: 0,      //名前のみ登録したい場合、初期値を指定する必要がある
  address: ""  //住所のみ登録したい場合、空文字を指定する必要がある
});

// ✅ Partialを使った場合（一部のプロパティだけでOK）
function registerUser(user: Partial<UserForm>) {
  // ユーザー登録処理
  console.log("ユーザーを登録しました:", user);
}

registerUser({
  name: "山田あああ",
});
```


### 3.テストデータの作成
#### ユーザー情報の一部分のみを変えて大量にテストデータを作成したいとき
`Partial<T>`を使用しない場合、登録項目をすべて指定しないと、ユーザー情報を作成できません。
`Partial<T>`を使うことで一部分のみ変更して、データを作成することができます。

```ts
type User = {
  id: number,
  name: string,
  email: string,
  age: number,
  isActive: boolean
}

// ❌ Partialなしの場合（すべてのプロパティが必要）
// 全プロパティを指定、一つずつ作成が必要
const user1 = {
  id: 1,
  name: "テスト花子",
  email: "hanako@example.com",
  age: 25,
  isActive: true
};

const user2 = {
  id: 2,
  name: "テスト花子",
  email: "hanako@example.com",
  age: 25,
  isActive: true
};



// ✅ Partialを使った場合（一部のプロパティだけでOK）
function createTestUser(override: Partial<User> = {}): User {
  // デフォルト値
  const defaultUser: User = {
    id: 999,
    name: "テストあああ",
    email: "test@example.com",
    age: 30,
    isActive: true
  };
  
  // デフォルト値と上書き値をマージ
  return { ...defaultUser, ...override };
}

// 名前だけ変えたユーザー
const user1 = createTestUser({ name: "山田あああ" });

// アクティブでないユーザー
const user2 = createTestUser({ isActive: false });
```

# ユーティリティ型
`Partial<T>`の他に全プロパティを必須にする`Required<T>`もあることに気づきました。
これらの型は大きくまとめるとユーティリティ型の一部ということを関連資料から学びました。

https://typescriptbook.jp/reference/type-reuse/utility-types

# おわりに
`Partial<T>`を個人で使いこなせるようになりつつ、他のユーティリティ型もマスターしていきたいです。

# 参考
https://qiita.com/Tsuyoshi84/items/e74109e2ccc0f4e625aa

https://typescriptbook.jp/reference/type-reuse/utility-types/partial

https://typescriptbook.jp/tips/shallow-copy-object#%E6%B5%85%E3%81%84%E3%82%B3%E3%83%94%E3%83%BC%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B

https://typescriptbook.jp/reference/type-reuse/utility-types/required

https://typescriptbook.jp/reference/type-reuse/utility-types