如何让函数仅接收实现指定接口的类的实例?
解决方案
TypeScript采用结构类型系统(鸭子类型),只要对象的结构与接口匹配,就会被认为符合该接口——这就是为什么Class2虽未显式实现CanDo,却能传入doSomething的核心原因。要实现仅允许Class1实例调用的需求,有以下几种可行方案:
方案一:用私有成员标记接口
给CanDo接口添加私有属性,只有显式实现该接口的Class1能拥有这个私有成员,Class2无法模拟私有成员的结构,从而被TypeScript拦截:
interface CanDo { someProperty: any; private readonly _canDoMarker: never; } class Class1 implements CanDo { someProperty: any; private readonly _canDoMarker: never = undefined!; } class Class2 { someProperty: any; } function doSomething(arg: CanDo) { callOtherFunction(arg.someProperty); } const object1 = new Class1(); const object2 = new Class2(); doSomething(object1); // 正常执行 doSomething(object2); // 类型错误:Class2缺少私有属性_canDoMarker
方案二:直接指定参数类型为Class1
如果不需要保留接口的抽象性,最直接的方式是把doSomething的参数类型改为Class1,从根源上限制传入的实例:
interface CanDo { someProperty: any; } class Class1 implements CanDo { someProperty: any; } class Class2 { someProperty: any; } function doSomething(arg: Class1) { // 直接用Class1替代CanDo callOtherFunction(arg.someProperty); } const object1 = new Class1(); const object2 = new Class2(); doSomething(object1); // 正常执行 doSomething(object2); // 类型错误:Class2不能赋值给Class1类型
方案三:使用品牌类型(Brand Type)
给CanDo类型添加唯一的品牌属性作为类型标识,只有Class1显式实现这个属性,Class2因缺少该属性无法通过类型检查:
type CanDo = { someProperty: any; _brand: 'CanDo'; // 品牌标识 }; class Class1 implements CanDo { someProperty: any; _brand: 'CanDo' = 'CanDo'; } class Class2 { someProperty: any; } function doSomething(arg: CanDo) { callOtherFunction(arg.someProperty); } const object1 = new Class1(); const object2 = new Class2(); doSomething(object1); // 正常执行 doSomething(object2); // 类型错误:Class2缺少_brand属性
内容的提问来源于stack exchange,提问作者sininen
相关产品推荐
相关产品推荐

