多态的这个关键字在方法体内没有按预期工作



代码正常运行:

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应该解析为undefinedwindow(取决于严格/草率模式)。在其他情况下,this可能是与Function.prototype.bindFunction.prototype.applyFunction.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允许输入接口(参数和返回值),但不包括实现方法的。

相关内容

最新更新