やっていいかは別として
バグの原因になるとか、OOPに反するとかいろいろあるけれど、interface
をextends
して継承元にあるプロパティを一部だけ上書きして別のプロパティにしたいみたいな気持ちになることがある(と思う)。
おさらい
interface A
があってそれを継承するinterface B
があるとする
interface A { foo: number bar: number baz: number qux: number yo: number } interface B extends A { cha: string }
これは普通に通る例
このinterface B
は実質こういう状態
interface B { foo: number bar: number baz: number qux: number yo: number cha: string }
OKですね。
プロパティを上書きしたいんだよね
yo
プロパティの型を継承した上でB独自にyo
だけ型を変更したい。
interface A { foo: number bar: number baz: number qux: number yo: number } interface B extends A { cha: string yo: string // Aにある"yo"はnumber型だがBではstring型にしたい }
これできそうな気がするけどやるとエラーになって
インターフェイス 'B' はインターフェイス 'A' を正しく拡張していません。 プロパティ 'yo' の型に互換性がありません。 型 'string' を型 'number' に割り当てることはできません。
と言われてしまう。
ハック技で実現できる
中継型を経由すれば実現可能
中継型で上書きしたいプロパティを一度any
にする
interface A { foo: number bar: number baz: number qux: number yo: number } // weakな中継用のinterfaceを用意する interface Bweaken extends A { yo: any } interface B extends Bweaken { cha: string yo: string }
yo
プロパティを変更したいので中継型Bweakenでyo
を一度anyにしておけばBでAを継承しつつプロパティを上書きできる
Util
type Weaken<T, K extends keyof T> = { [P in keyof T]: P extends K ? any : T[P] }
こういうのべんり君を用意すると
interface B extends Weaken<A, 'yo'> { cha: string yo: string }
便利っぽい。