我的一些代码中有一个工厂方法,我不仅要传递要实例化的Class类型,还要传递一组默认值以供类中的属性使用。我想获得类型,以便编译器将告诉我是否尝试传入实例化的类类型中不存在的属性。我不知道如何做到这一点。
这是一个简单的示例,显示了我想做什么。
尝试时,出现编译器错误:“一个接口只能扩展一个类或另一个接口。” 接口,ClassProps
因为它不能从扩展T
。
class Base {
myId: number;
}
class Klass1 extends Base {
myString: string;
myNumber: number;
}
interface IBaseCtr<T> {
new (): T;
}
// Get an interface that is the properties of the class passed
interface ClassProps<T extends Base> extends T {}
// This method compiles, but doesn't check the prop names
//function factory<T extends Base>(ctrFunc: IBaseCtr<T>,
// initialData?: Object): T
function factory<T extends Base>(ctrFunc: IBaseCtr<T>,
initialData?: ClassProps<T>): T
{
let new_obj = new ctrFunc();
Object.assign(new_obj, initialData);
return new_obj;
}
let v1 = factory(Klass1, {myId: 10, myString: 'foo'});
let v2 = factory(Klass1, {badVar: 10});
有任何想法如何initialData
输入,以便badVar
在第二次调用中将其标记为不允许输入吗?
我认为这是一个可爱的问题。
这是我的方法。完全删除该接口。
function factory<T extends V, V extends Base>(ctrFunc: IBaseCtr<T>,
initialData?: V): T
{
let new_obj = new ctrFunc();
Object.assign(new_obj, initialData);
return new_obj;
}
这样就建立了一个层次结构,Base是V中属性的子集,它本身也是T(您的最终类型)中属性的子集。v1被分配而没有错误。v2的赋值语句在编译时导致错误。
您实际上可以继续删除该extends Base
部分,以使此功能可在更多地方使用。它将仍然以相同的方式进行类型检查。
对于傻笑,类型正确检查的完全独立的工厂功能签名:
function factory<T extends V, V>(ctrFunc: new () => T,
initialData?: V): T
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句