TypeScriptにおける分割代入を使った引数受け渡し

以下のような関数を考えてみましょう。

interface Student {
  id: number;
  name: string;
  class: string;
  sex: string;
}

function matriculation(student: Student) {
  // ...
}

この関数を呼び出すには、Studentインターフェースの制約を満たすオブジェクトを渡す必要があります。

interface Student {
  id: number;
  name: string;
  class: string;
  sex: string;
}

function matriculation(student: Student) {
  // ...
}

const lihua: Student = {
  id: 1,
  name: 'Lihua',
  class: '1A',
  sex: 'Female',
};

matriculation(lihua);

ここまでは問題ありません。次に、この関数で渡された引数の各プロパティを表示したいとします。分割代入を使わない場合のコードは以下の通りです。

function matriculation(student: Student) {
  console.log(`名前${student.name}`);
  console.log(`クラス${student.class}`);
  console.log(`性別${student.sex}`);
  console.log(`学籍番号${student.id}`);
}

ご覧の通り、毎回student.と記述する必要があり、コードが冗長になります。そこで、分割代入を使って引数を受け取ることで簡潔にできます。

function matriculation({ id, name, sex, grade }: Student) {
  console.log(`学籍番号${id}`);
  console.log(`名前${name}`);
  console.log(`性別${sex}`);
  console.log(`学年${grade}`);
}

これでずっとスッキリしました。

さらに高度な使い方も考えてみましょう。例えば、高学年の生徒は学校に既に情報が登録されているため、入学手続きには学籍番号だけでよく、他の値はデフォルト値を使えるようにしたいとします。その場合、関数とインターフェースを次のように変更します。

interface Student {
  id: number;
  name: string;
  grade: string;
  sex: string;
}

type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

これにより、関数は一部の値が省略された引数を受け取れるようになります。 OptionalStudent型の説明図

次にデフォルト値を設定します。分割代入を使わない場合のコードは次の通りです。

type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

function matriculation(student: OptionalStudent<Student, 'name' | 'grade' | 'sex'>) {
  const defaultStudent: Student = {
    id: 0,
    name: 'Unknown',
    grade: 'Unknown',
    sex: 'Unknown',
  };
  const studentWithDefault = { ...defaultStudent, ...student };
  console.log(`学籍番号${studentWithDefault.id}`);
  console.log(`名前${studentWithDefault.name}`);
  console.log(`学年${studentWithDefault.grade}`);
  console.log(`性別${studentWithDefault.sex}`);
}

このコードは冗長で、まずデフォルトオブジェクトを宣言し、それを分割代入と引数のオブジェクトをマージしてから上書きしています。記述もロジックも無駄が多いです。

このような場合も、分割代入のデフォルト値機能を使うことで改善できます。

type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

function matriculation({ id, name = 'Unknown', grade = 'Unknown', sex = 'Unknown' }: OptionalStudent<Student, 'name' | 'grade' | 'sex'>) {
  console.log(`学籍番号${id}`);
  console.log(`名前${name}`);
  console.log(`学年${grade}`);
  console.log(`性別${sex}`);
}

タグ: TypeScript 分割代入 インターフェース 型ユーティリティ デフォルト値

5月22日 13:53 投稿