TypeScript中如何重写类型且仅允许继承接口的属性?
TypeScript中限制接口仅重写继承属性的实现方法
要实现仅允许重写继承接口的属性、新增属性直接报错的需求,普通的extends继承无法做到(TypeScript默认允许接口继承后新增属性),但可以通过结合工具类型实现定义时的错误提示:
实现方案
保留原接口A的定义,通过自定义工具类型约束新增属性,再让接口B同时继承原接口和这个工具类型:
interface A { Foo: unknown; Bar: any; } // 工具类型:仅包含接口A的所有键(可选属性形式,不影响原属性必填性) type StrictInherit<T> = { [K in keyof T]?: T[K]; }; // 接口B同时继承A和StrictInherit<A> interface B extends A, StrictInherit<A> { Foo: string; // 合法:重写A中已有的Foo属性类型 Bar: number; // 合法:重写A中已有的Bar属性类型 // Foobar: string; // 非法:新增属性会直接报错,提示“Foobar不在StrictInherit<A>的属性中” }
原理说明
StrictInherit<T>会生成仅包含T所有键的类型,当B继承它时,TypeScript会检查B的所有属性是否都属于A的键集合,新增不在A里的属性会触发编译错误。- 同时继承
A是为了保留原属性的约束(比如必填性),避免工具类型的可选属性影响原接口行为。
替代方案(类型别名形式)
如果可以接受用类型别名而非接口,写法更简洁,同样能实现限制:
interface A { Foo: unknown; Bar: any; } // 用Omit排除要重写的属性,再交叉重写后的类型 type B = Omit<A, 'Foo' | 'Bar'> & { Foo: string; Bar: number; // Foobar: string; // 非法:新增属性会报错,提示类型不匹配 };
这种方式下,类型B完全基于A的结构,新增不属于A的属性会直接触发类型检查错误。
内容的提问来源于stack exchange,提问作者thegreenmilecasablanca
相关产品推荐
相关产品推荐

