如何让typescript了解动态添加到类中的静态成员的存在?
我有一个如何让typescript了解动态添加到类中的静态成员的存在?,typescript,Typescript,我有一个QueryBuilder,我想在Model类中以静态成员的形式展示它的所有方法 显然,这是有效的Javascript代码。然而,我怎样才能让typescript理解模型上存在的那些静态方法呢 function queryable (target: any) { for (const prop in target.prototype.builder) { if (prop === 'constructor' || target.prototype.hasOwnProperty(
QueryBuilder
,我想在Model
类中以静态成员的形式展示它的所有方法
显然,这是有效的Javascript代码。然而,我怎样才能让typescript理解模型上存在的那些静态方法呢
function queryable (target: any) {
for (const prop in target.prototype.builder) {
if (prop === 'constructor' || target.prototype.hasOwnProperty(prop)) {
continue;
}
target[prop] = (...args: any[]): any => {
return target.prototype.builder[prop](...args);
};
}
}
class QueryBuilder {
where(prop: string, value: string) {
console.log(prop, value);
console.log("I've presented on model class as static method.");
}
// ...
}
@queryable
class Model {
get builder () {
return new QueryBuilder();
}
// ...
}
// calling static where
Model.where('color', 'red');
类型“typeof Model”上不存在属性“where”
请参见中的内容,因为Typescript是一种强大的键入语言,所以它总是检查类型用法是否与类型接口匹配。当Typescript不知道您要添加一个新方法时,这种检查会在传输过程中进行。因为您是在运行时添加它的。调用这样一个方法的唯一方法是将其转换为像any
:
(<any>Model).where('color', 'red');
(型号)。其中('color','red');
这就像你对Typescript说,你确信方法的存在,transpiller不应该担心它。你应该注意的问题是,到目前为止(3.5.1),装饰器无法更改它所装饰的类的类型
也就是说,您仍然可以以相同的方式定义decorator,但是显式地调用它,而不是作为decorator,正如许多使用redux流行的connect
decorator的typescript项目所做的那样
class _Model {
get builder () {
return new QueryBuilder();
}
// ...
}
const Model = queryable(_Model);
或者,如果它是模块的主要导出,您可以使用一个名称:
class Model {
get builder () {
return new QueryBuilder();
}
// ...
}
export default queryable(Model);
然后,诀窍是更好地为装饰程序添加注释,以教授typescript对其目标所做的所有添加queryable
:
function queryable<T extends new (...args: any[]) => {builder: any}>(target: T): InstanceType<T>['builder'] & (typeof target) {
for (const prop in target.prototype.builder) {
if (prop === 'constructor' || target.prototype.hasOwnProperty(prop)) {
continue;
}
(target as any)[prop] = (...args: any[]): any => {
return target.prototype.builder[prop](...args);
};
}
return target as any
}
函数可查询{builder:any}>(目标:T):InstanceType['builder']&(typeof目标){
for(target.prototype.builder中的常量属性){
if(prop=='constructor'| | target.prototype.hasOwnProperty(prop)){
继续;
}
(目标为任意)[prop]=(…args:any[]):any=>{
返回target.prototype.builder[prop](…args);
};
}
返回任何目标
}
好的观点。我不介意显式实现。然而,实际上,模型
类也接受一种类型,即,类模型扩展…
,我想知道在调用queryable(Model)
的示例中如何解决这种情况?这应该没有问题。参数的类型只是一个具有生成器属性的类。返回类型表示它是同一类加上生成器字段。+1。因此,在这里解决我的原始问题,帮助Typescript理解动态添加的静态成员将是一个连接器,如const connect={builder:any}>(target:T):InstanceType['builder']&(typeof target)=>target代码>然后<代码>常量模型=连接(原始模型)谢谢你,伙计。这是一个消除错误的变通方法,但我宁愿不施放,而是改变目标。