我有以下class decorator factory接受初始化函数作为其参数。在这个initializer
函数中,我想返回一个对应于所涉及的类类型(或派生类型)的实例:
function JsonObject<T>(initializer: (json: any) => T) {
return function (target: { new (...args: any[]): T }) {
// ...
}
}
@JsonObject(function (json) {
return new Animal();
})
class Animal {
name: string;
}
返回确切类的实例(如上所述)可以正常工作,但是......
返回派生类的实例不是。我可以返回 base 实例,但不能返回派生的实例。例如,我无法返回Cat
:
@JsonObject(function (json) {
return new Cat(); // Error.
})
class Animal{
name: string;
}
class Cat extends Animal {
color: string;
}
......即使Cat 是动物。但是,对于猫来说,我可以返回 Animal 而不是Cat(这是一个错误,因为动物不一定是猫):
@JsonObject(function (json) {
return new Animal(); // OK, but it shouldn't be
})
class Cat extends Animal {
color: string;
}
JsonObject
函数类似于具有泛型类型参数T
的函数,接受回调函数返回T
作为其参数,并返回接受a的函数返回T
的newable类型。后者(返回的函数)显然是class decorator本身。
编译器不允许我 - 例如 - 从这个initializer
函数(或任何其他不匹配类型)返回一个字符串,这应该是应该的。
但是,当使用子类型时,上述类型签名的行为完全相反:从initializer
函数我可以返回 base 类型,但不能返回派生< / em> type - 在两步继承模式的中间类上使用时发生以下错误:
@JsonObject(function (json) {
// Test case: return a base type.
return new Animal(); // OK, but it shouldn't be: an 'Animal' is not a 'Cat'
})
@JsonObject(function (json) {
// Test case: return an exact corresponding type.
return new Cat(); // OK, as it should be
})
@JsonObject(function (json) {
// Test case: return a derived type.
return new Kitty(); // <-- Error, but it should be OK, a Kitty *is* a Cat
})
class Cat extends Animal {
color: string;
}
class Kitty extends Cat {
cutenessFactor: number;
}
错误:输入&#39; Cat&#39;不能分配给&#39; Kitty&#39;。物业&#39; cutenessFactor&#39;类型&#39; Cat&#39;
中缺少
我相信我已经确定了错误的起源,它是由编译器在推断泛型时引起的:泛型类型参数T
是从&#34; T&#34推断出来的; 在initializer: (json: any) => T
中,这意味着错误是由具有泛型类型Kitty
的JsonObject函数引起的,Cat
显然不能分配给它,因此该类在这种情况下,不能在Cat
上使用装饰器。
我希望这样,T
可以从&#34; return&#34;中推断出来。类型target
,这将解决我的问题。我怎么能做到这一点?
当然,当我明确指定泛型类型参数时,它可以完美地工作(但这会带来多余的信息):
@JsonObject<Cat>(function (json) {
return new Kitty(); // OK, since type 'Kitty' is assignable to type 'Cat'
})
class Cat extends Animal { }
答案 0 :(得分:0)
你的意思是链接装饰者还是你的意思是这样:
zPosition
如果你的意思是上面^它编译得很好