Generics TypeScript中的泛型类型参数推断优先级
下面是接受初始值设定项函数作为参数的例子。在这个Generics TypeScript中的泛型类型参数推断优先级,generics,typescript,decorator,Generics,Typescript,Decorator,下面是接受初始值设定项函数作为参数的例子。在这个初始值设定项函数中,我想返回一个与所涉及的类类型(或派生类类型)对应的实例: 返回精确类的实例(如上所述)可以正常工作,但是 短版 返回派生类的实例不会导致错误。我可以返回基本实例,但不能返回派生实例。例如,我无法返回一个Cat: @JsonObject(function (json) { return new Cat(); // Error. }) class Animal{ name: string; } class Cat
初始值设定项函数中,我想返回一个与所涉及的类类型(或派生类类型)对应的实例:
返回精确类的实例(如上所述)可以正常工作,但是
短版
返回派生类的实例不会导致错误。我可以返回基本实例,但不能返回派生实例。例如,我无法返回一个Cat
:
@JsonObject(function (json) {
return new Cat(); // Error.
})
class Animal{
name: string;
}
class Cat extends Animal {
color: string;
}
。。。即使猫是动物。但是,我可以退回一只动物而不是猫(这是错误的,因为动物不一定是猫),因为猫:
@JsonObject(function (json) {
return new Animal(); // OK, but it shouldn't be
})
class Cat extends Animal {
color: string;
}
长版本
JsonObject装饰工厂
JsonObject
函数类似于具有泛型类型参数T
的函数,它接受一个回调函数,返回一个T
作为其参数,并返回一个函数,该函数接受一个新类型,返回一个T
。后者(返回的函数)显然是函数本身
例如,编译器不允许我从这个初始值设定项
函数(或任何其他不匹配的类型)返回字符串,这是应该的
子类型问题
但是,当使用子类型时,上述类型签名的行为方式正好相反:从初始值设定项
函数中,我可以返回基类型,但不能返回派生类型——在两步继承模式的中间类上使用时,会发生以下错误:
@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;
}
你的意思是连锁装饰店还是说:
function JsonObject<T>(initializer: (json: any) => T) {
return function (target: { new (...args: any[]): T }) {
return null;
}
}
@JsonObject(function (json) {
return new Foo();
})
class Foo {
foo: string;
}
@JsonObject(function (json) {
// Test case: return an exact corresponding type.
return new Bar(); // OK, as it should be
})
class Bar extends Foo {
bar: string;
}
@JsonObject(function (json) {
// Test case: return a derived type.
return new Baz(); // Ok
})
class Baz extends Bar {
baz: string;
}
函数JsonObject(初始值设定项:(json:any)=>T){
返回函数(目标:{new(…args:any[]):T}){
返回null;
}
}
@JsonObject(函数(json){
返回新的Foo();
})
福班{
foo:string;
}
@JsonObject(函数(json){
//测试用例:返回精确的对应类型。
返回new Bar();//按原样确定
})
类栏扩展了Foo{
酒吧:字符串;
}
@JsonObject(函数(json){
//测试用例:返回一个派生类型。
返回新的Baz();//确定
})
类Baz扩展条{
baz:字符串;
}
如果您指的是上面的^it编译很好您是指链接装饰程序还是指:
function JsonObject<T>(initializer: (json: any) => T) {
return function (target: { new (...args: any[]): T }) {
return null;
}
}
@JsonObject(function (json) {
return new Foo();
})
class Foo {
foo: string;
}
@JsonObject(function (json) {
// Test case: return an exact corresponding type.
return new Bar(); // OK, as it should be
})
class Bar extends Foo {
bar: string;
}
@JsonObject(function (json) {
// Test case: return a derived type.
return new Baz(); // Ok
})
class Baz extends Bar {
baz: string;
}
函数JsonObject(初始值设定项:(json:any)=>T){
返回函数(目标:{new(…args:any[]):T}){
返回null;
}
}
@JsonObject(函数(json){
返回新的Foo();
})
福班{
foo:string;
}
@JsonObject(函数(json){
//测试用例:返回精确的对应类型。
返回new Bar();//按原样确定
})
类栏扩展了Foo{
酒吧:字符串;
}
@JsonObject(函数(json){
//测试用例:返回一个派生类型。
返回新的Baz();//确定
})
类Baz扩展条{
baz:字符串;
}
如果您是指上面的^it compiles fine是的,我是指单独使用,尽管关于类类型,我相信TypeScript编译器不识别类装饰器。除非我遗漏了什么,否则这并不重要。问题是
JsonObject
中的泛型类型参数T
是从初始值设定项
函数返回的值推断出来的,而不是从目标
构造函数返回的值推断出来的。这可以很好地编译。不是吗?确实是这样。但是,如果要在应用于Foo
的装饰器中返回Bar
的实例,则会出现错误。这是因为编译器如何根据返回的内容推断出JsonObject
的泛型类型。是的,我的意思是单独使用,尽管关于类类型,我相信TypeScript编译器不识别类装饰器。除非我遗漏了什么,否则这并不重要。问题是JsonObject
中的泛型类型参数T
是从初始值设定项
函数返回的值推断出来的,而不是从目标
构造函数返回的值推断出来的。这可以很好地编译。不是吗?确实是这样。但是,如果要在应用于Foo
的装饰器中返回Bar
的实例,则会出现错误。这是由于编译器如何根据返回的内容推断出JsonObject
的泛型类型。
function JsonObject<T>(initializer: (json: any) => T) {
return function (target: { new (...args: any[]): T }) {
return null;
}
}
@JsonObject(function (json) {
return new Foo();
})
class Foo {
foo: string;
}
@JsonObject(function (json) {
// Test case: return an exact corresponding type.
return new Bar(); // OK, as it should be
})
class Bar extends Foo {
bar: string;
}
@JsonObject(function (json) {
// Test case: return a derived type.
return new Baz(); // Ok
})
class Baz extends Bar {
baz: string;
}