かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

TypeScript interface のプロパティを引数に取る関数を定義したい

例えば次ようなサインアップフォームのフィールドの値を引数に取るバリデーションを行う関数あるとして、この関数の型を別途定義したい

interface SignUp {
  username: string;
  email: string;
  password: string;
}

const validation = ({ username, email, password }: Partial<SignUp>): boolean = {...}
// => この関数の型を別途定義したい

引数が interface のオブジェクトのままなら [key in keyof Interface] を使って型定義できる

interface SignUp {
  username: string;
  email: string;
  password: string;
}

type ValidationFuncType = (arg: Partial<SignUp>) => boolean;

const validation: ValidationFuncType = ({ username, email, password }) => {}

オブジェクト展開して関数で受け取っているので、arg: Partial<[key in keyof SignUp]> の様な定義ができる。関数の型定義のとろこにオブジェクトを分割した際の引数を書かなくても関数の引数で保管が効くようになりる。 type F = (Partial<[key in keyof SignUp]>) => boolean のうような書き方はできないっぽい。

validation 関数が受け取る値が new FormData で取得する値なら次のように定義できる

type ValidationFuncType = (arg: Partial<{
  [key in keyof SignUp] : FormDataEntryValue | null;
}>) => boolean;

受け取るプロパティを追加したい場合は & (intersection) で引数のオブジェクトのプロパティを追加してしまえばOK

type ValidationFuncProps = Partial<{
  [key in keyof SignUp] : FormDataEntryValue | null;
}> & {
  isSignUp: boolean;
};

type ValidationFuncType = (arg: ValidationFuncProps) => boolean;

// isSignUp の型補完も効くようになる!
const validation: ValidationFuncType = ({ username, email, password, isSignUp }) => {}

渡さないプロパティがある場合は Omit で取り除けば良さそう

もっと良い定義方法があれば教えて下さい!


[参考]