代码正常运行:
class Foo {
axisControl: string = "string";
directionControl: string = "string";
filteredAxis: string[] = ["string"];
filteredDirection: string[] = ["string"];
test(filteredName: `filtered${string}` & keyof Foo) {
this[filteredName] = ["otherString"];
}
}
this[filteredName]
成功解析为string[]
类型。但是,它意味着类用它的名称引用自己。我想使用多态this
代替:
class Foo {
axisControl: string = "string";
directionControl: string = "string";
filteredAxis: string[] = ["string"];
filteredDirection: string[] = ["string"];
test(filteredName: `filtered${string}` & keyof this) { // polymorphic this
this[filteredName] = ["otherString"]; // Type 'string[]' is not assignable to type 'this[`filtered${string}` & keyof this]'.
}
}
但由于某种原因,它不工作,解决的类型是this[`filtered${string}` & keyof this]
,这不允许我做任何事情。
取决于方法是在类的实例上调用还是在扩展类的实例上调用,基于this
的最终类型可能会有所不同,这就是为什么它不会在函数体中解析,因为它还不知道执行上下文。
下面的代码也有存在的可能,并且是完全有效的:
const test = Foo.prototype.test;
test("filteredAxis");
在这种情况下,this
应该解析为undefined
或window
(取决于严格/草率模式)。在其他情况下,this
可能是与Function.prototype.bind
、Function.prototype.apply
或Function.prototype.call
绑定的对象。
但是,编译器没有像预期的那样抛出任何错误。但是有可能通过像这样显式地注释方法来强制执行:
test(this: this, filteredName: `filtered${string}` & keyof Foo)
这里有一个正在进行的讨论,关于默认情况下启用此行为的标志:https://github.com/microsoft/TypeScript/issues/7968
但是,即使启用了这种行为,由于可能存在扩展类,类型在函数体内也无法解析。
TL;博士
在方法体内部,编译器不知道调用该方法的可能的扩展类,因此基于this
的类型无法解析。只有当编译器知道实际的类是什么时,它们才会这样做。
class Foo {
axisControl: string = "string";
directionControl: string = "string";
filteredAxis: string[] = ["string"];
filteredDirection: string[] = ["string"];
test(filteredName: `filtered${string}` & keyof this) { // polymorphic this
return this[filteredName]; // Type does not resolve here (unknown current class)
}
}
const foo = new Foo;
const result = foo.test("filteredAxis"); // But it does here: string[]
作为结论,this
允许输入接口(参数和返回值),但不包括实现方法的。