You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:03:38