かもメモ

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

TypeScript 特定のキーを持つオブジェクトの型

オブジェクトの特定のプロパティの値をアップデートをする関数を作成していました

interface Todo {
  name: string;
  description: string;
}

const todo: Todo = { name: "", description: "" };

const update = (arg: {name?: string; description?: string}): Todo => {
  return {
    ...todo,
    ...arg
  };
};

update 関数の引数の型を interface を使っていい感じにしたい…

NG: [key: union 型] ではエラーになる

{ [key: 'name' | 'description']?: string } という型を作ればいいと思ったのですが、これはエラーになってしまいます

type ArgType = { [key: 'name' | 'description']?: string };

=> An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead

OK: [key in union 型] を使えばOK

[key in 'name' | 'description'] という形であればOK

type ArgType = { [key in 'name' | 'description']?: string };
/* 👇
type ArgType = {
    name?: string | undefined;
    description?: string | undefined;
}
/*

interface から union型を作る

interface Todo の key の集合は keyof Todo で取得できるので、[key in keyof Todo] とすれば良い
Mapped types って言うらしい

interface Todo {
  name: string;
  description: string;
}

const todo: Todo = { name: "", description: "" };

const update = (arg: [key in keyof Todo]?: string}): Todo => {
  return {
    ...todo,
    ...arg
  };
};

₍ ᐢ. ̫ .ᐢ ₎ できた。

やったことある気がする…って思ってたら案の定同じような記事を過去に書いてたぬ…


[参考]

カラマリ・ユニオン良いよね…