在以下TypeScript代码中的“ this”上,出现以下错误:
类型'this'的参数不能分配给类型'T'的参数。 类型“ MyClass”不能分配给类型“ T”。ts(2345)
以TypeScript 3.2.2(在Angular 7中)编写
export abstract class MyClass<T extends MyClass<T>> {
childList: T[];
foo = () => {
const index = this.childList.indexOf(this);
// ...
}
}
这就是我用C#编写的方式:
public abstract class MyClass<T> where T : MyClass<T>
{
public T[] childList { get; set; }
public void foo()
{
int index = Array.IndexOf(childList, this);
}
}
非常感谢您的反馈!
答案 0 :(得分:3)
我不确定C#,但是在TypeScript中,您声明T extends MyClass<T>
,这意味着T
是MyClass<T>
的子类型, 与{em> MyClass<T>
不相同。因此,类型T
的任何值都可以分配给类型MyClass<T>
的变量,反之亦然。
Array<X>.indexOf(y)
的{{3}}期望y
可分配给X
,反之亦然。因此,在类型为Array<T>.indexOf()
的参数上调用MyClass<T>
是错误的。解决此问题的一种方法是声明childList
的类型为Array<MyClass<T>>
而不是Array<T>
:
childList!: MyClass<T>[];
但就我所知,这可能会在其他地方出现,因为在某些时候您会假设T
与MyClass<T>
相同,事实并非如此。 。您随时可以使用type definition来解决问题,但我认为您可能需要一个完全不同的解决方案:type assertions。
使用类型Foo<T extends Foo<T>>
来表示“当前类的类型”,而不是尝试表示诸如this
之类的循环/递归类型,而是使用自己的尾巴。您的MyClass
变为:
export abstract class MyClass {
childList!: this[];
foo() {
const index = this.childList.indexOf(this); // okay
}
}
和子类或多或少按您期望的方式工作:
export class MyConcreteClass extends MyClass {
bar() {
this.childList.indexOf(this); // still works
}
}
实例将this
兑现为实例的实际类型:
const y = new MyConcreteClass();
y.childList; // type MyConcreteClass[];
希望有所帮助;祝你好运!