typescript - TypeScript 中的“扩展”与 C# 中对泛型的约束不同
问题描述
在以下 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);
}
}
非常感谢任何反馈!
解决方案
我不确定 C#,但在 TypeScript 中,您声明的是T extends MyClass<T>
,这意味着它T
是 的子类型,MyClass<T>
与. MyClass<T>
因此,任何类型的值T
都可以分配给类型的变量MyClass<T>
,但反之则不行。
的类型定义Array<X>.indexOf(y)
期望y
可分配给,X
反之亦然。所以调用Array<T>.indexOf()
类型参数是错误的MyClass<T>
。解决此问题的一种方法是声明childList
为 typeArray<MyClass<T>>
而不是Array<T>
:
childList!: MyClass<T>[];
但据我所知,这会在其他地方显示为一个问题,因为在某些时候你会想假设它T
与 相同MyClass<T>
,但事实并非如此。您始终可以使用类型断言来解决问题,但我认为您可能需要一个完全不同的解决方案:多态this
。
与其尝试表示循环/递归类型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[];
希望有帮助;祝你好运!
推荐阅读
- ios - 尝试将过滤器与 Swift 4、IOS 11 一起使用时出现错误消息
- javascript - 这两行代码有什么区别?
- javascript - 反应不渲染类
- javascript - 如果未单击页面,为什么 onbeforeunload 不会触发?
- c# - 通过位移组合两个可变长度的字节数组
- php - 如何将数据从控制器传递到codeigniter3中的自定义钩子
- javascript - 如何在 vis.js 时间线中获取开始和结束时间?
- mysql - MYSQL - 如何使用 group by 获取每个类型字段中的最新记录
- vba - 循环隐藏工作表
- java - 仅当子字符串是整个单词时才替换字符串中的所有子字符串