TypeScript

TypeScript でオブジェクトの 1 プロパティだけを書き換える型安全な関数を定義する

こんな感じ。
Index Types を使うのがミソ。

interface User {
    first_name: string;
    last_name: string;
    first_name_kana: string;
    last_name_kana: string;
    birth_year: number;
    birth_month: number;
    birth_day: number;
}

function updateUserProperty<P extends keyof User>(user: User, propName: P, value: User[P]): User {
    return {
        ...user,
        [propName]: value,
    }
}

すると、この関数にこんなパラメータを渡すと、型エラーになる。

const user: User = {
    first_name: '雄也',
    last_name: '竹山',
    first_name_kana: 'Yuya',
    last_name_kana: 'Takeyama',
    birth_year: 1987,
    birth_month: 3,
    birth_day: 19,
};

const updatedUser = updateUserProperty(user, 'birth_year', '1984');

image.png

まぁこれ自体はあまり役に立たないですが、汎用的な Redux Action Creator とかを定義するときに応用できるかも。

さらなる一般化を試みる、が...

こんな感じにしてみたのですが、

function updateObjectProperty<T, P extends keyof T>(obj: T, propName: P, value: T[P]): T {
    return {
        ...obj,
        [propName]: value,
    }
}

...obj のところがエラーになってしまいます。

image.png

T extends object とかしても解決しないようです。
解決方法わかる方いたら教えてください。