[英]TypeScript: Polymorphic this and inferring generic function parameter
I would like to infer the type of the current class from this
keyword passed to a function.我想从传递给 function 的this
关键字推断当前 class 的类型。 For some reason when i'm passing this
as a parameter to the function, TypeScript infers that type parameter T is this
instead of the current class type.由于某种原因,当我this
作为参数传递给 function 时,TypeScript 推断类型参数 T 是this
而不是当前的 class 类型。
Below there is an example of what i'm trying to do.下面有一个我正在尝试做的例子。 I want both B
and C
class to have a field
with a type number
, but the field
in C class is GenericArguments<this>
when passing this
as argument. I want both B
and C
class to have a field
with a type number
, but the field
in C class is GenericArguments<this>
when passing this
as argument. When type is specified manually everything works fine ( B
class example), but inferring the type from this
does not give the results i want.当手动指定类型时,一切正常( B
class 示例),但从this
推断类型并不能给出我想要的结果。
type GenericArgument<T> = T extends A<infer R> ? R : never;
function test<T>(obj: T): GenericArgument<T> {
// do operations
// return ...;
}
class A<T> {
something: T;
}
class B extends A<number> {
field = test<B>(this); // <-- field has a type: number
}
class C extends A<number> {
field = test(this); // <-- field has a type: GenericArgument<this>
}
Do i need some additional keyword to force TypeScript to use current class type and not polymotphic this
?我需要一些额外的关键字来强制 TypeScript 使用this
的 class 类型而不是多形的吗? Or is there some other way to achieve this?还是有其他方法可以实现这一目标?
this
is not of the same type as the class. this
与 class 的类型不同。 It has a special type, the polymorphic this
type.它有一个特殊的类型,多态的this
类型。 The polymorphic this
type represents the type of the current class and will be seen from the outside as whatever the type of the current class is. this
类型的多态表示当前 class 的类型,无论当前 class 的类型是什么类型,都可以从外部看到。 So for example this works:因此,例如,这有效:
class A {
getThis() { return this; }
getA(): A { return this; }
}
class B extends A {
method() { }
}
var b = new B();
b.getThis().method(); // ok since polymorphic this is seen as B from the outside
b.getA().method(); // err since we are accessing on A
From inside the class, this has the unfortunate side effect that the this
type has to behave as an unresolved type parameter (one that extends
the current class).从 class 内部来看,这具有不幸的副作用,即this
类型必须表现为未解析的类型参数( extends
当前类的参数)。 This is due to the fact that the final type of this
is indeed not yet fully known. this
是因为它的最终类型确实还不完全清楚。
Since the polymorphic this
type is behaves like an unresolved type parameter, typescript is very limited in what it will do with it in conditional types.由于this
类型的多态行为类似于未解析的类型参数,因此 typescript 在条件类型中的作用非常有限。 Typescript does not generally resolve conditional types that still contain unresolved type parameters. Typescript 通常不解析仍包含未解析类型参数的条件类型。
From outside the class, the type of field
will be resolved correctly, since polymorphic this
is resolved to whatever type we access field
on.从 class 外部, field
的类型将被正确解析,因为多态this
解析为我们访问field
的任何类型。 We might even have some surprises if the type of something
is narrowed by a derived class (which is possible):如果something
的类型被派生的 class (这是可能的)缩小范围,我们甚至可能会感到惊讶:
class C extends A<number> {
field = test(this); // <-- field has a type: GenericArgument<this>
}
new C().field // is number
class D extends C {
something!: 1
}
new D().field // is of type number literal type 1
The workaround of being explicit with the field number is probably the simplest one.明确使用字段编号的解决方法可能是最简单的解决方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.