TypeScript如何定义禁止包含指定属性的interface接口?
TypeScript 定义禁止指定属性的接口方案
你可以通过将目标属性设为可选never类型实现需求,这种写法会完全禁止接口对应实例出现该属性,不需要强制声明属性为undefined。
核心语法
要禁止属性scale存在,写法如下:
interface NoScale { scale?: never; }
和原有写法的区别
- 你之前写的
scale: undefined:要求实例必须存在scale属性,且值只能是undefined scale?: never:要求实例完全不能存在scale属性,一旦声明就会触发类型报错
适配Mixin场景
你需要避免属性冲突的Mixin重复加载,只需要修改NoScale的泛型约束,指定你要禁止的属性即可。比如你要禁止传入的基类已经存在scale属性,代码调整如下:
type Constructor = new (...args: any[]) => {}; type GConstructor<T = {}> = new (...args: any[]) => T; class Sprite { name = ''; x = 0; y = 0; constructor(name: string) { console.log('@constructor'); this.name = name; this.x = 12; } } function Scale<TBase extends Constructor>(Base: TBase) { return class Scaling extends Base { theScale = 1; setScale(scale: number) { this.theScale = scale; } get scale(): number { return this.theScale; } }; } // 约束:传入的基类实例不能存在scale属性 type NoScale = GConstructor<{ scale?: never }>; function ScaleTwo<TBase extends NoScale>(Base: TBase) { return class ScalingTwo extends Base { theScale = 1; setScale(scale: number) { console.log('OVERWRITTEN'); } get scale(): number { console.log('OVERWRITTEN get'); return this.theScale + 5; } }; } // 此时会触发编译报错:因为Scale(Sprite)返回的类已经存在scale属性,不符合NoScale约束 // 如果你传入的是没有scale属性的Sprite类,就不会报错 const EightBitSpriteMixin = ScaleTwo(Scale(Sprite));
现有代码说明
你原有代码里写的是禁止setPosds属性,而Scale(Sprite)返回的类本身就没有setPosds属性,所以如果你希望只有当基类存在setPosds时才报错,那原有写法逻辑是正确的,不需要调整。
内容的提问来源于stack exchange,提问作者Ruslan Plastun
相关产品推荐
相关产品推荐

