課題
オブジェクトの型で、プロパティの追加や削除ではなく、存在する型を上書きしたい場合はどうすればよいでしょうか?
Person
という型を用意して、birthday
というプロパティの型を、
Date
からstring
に変更する場合を考えてみます。
interface Person {
id: number
name: string
birthday: Date
}
継承してみる
まず、extends
を使って、継承してみましょう
interface Person2 extends Person {
birthday: string
}
すると、Date
にstring
は適用できないと、エラーが表示されます。
Interface 'Person2' incorrectly extends interface 'Person'.
Types of property 'birthday' are incompatible.
Type 'string' is not assignable to type 'Date'.ts(2430)
解決方法
プロパティの型を変換する汎用的な型を作成する
// プロパティの型変換
type ConvertPropetyType<T, E> =
Pick<T, Exclude<keyof T, keyof E>> &
Pick<E, Extract<keyof E, keyof T>>
ジェネリクスの第1引数に変換元の型を指定、第2引数に、変換したいプロパティと型を指定します。
変換した型を作成してみます。
type Person2 = ConvertPropetyType<Person, { birthday: string }>
今度はエラーは発生しません。
実際に、オブジェクトに適用してみます。
const person1: Person2 = {
id: 1,
name: 'name',
birthday: new Date(),
}
変換前のDate
型を実装すると、Type 'Date' is not assignable to type 'string'.ts(2322)
というエラーが発生します。
const person1: Person2 = {
id: 1,
name: 'name',
birthday: '2000-01-01',
}
変換後のstring
で実装すると、エラーが発生せず、期待通りに型が適用できました。