typescript - T 类型的参数不可分配给 T 类型的参数其中 Y 是 X 的子类
问题描述
我的目标是让父类定义事件,并让子类为它们触发事件,但在这些事件中传递的类型将取决于子类,但它将属于某个基类。很难用语言表达,所以这是我的简化 TypeScript 代码,它仍然会产生错误:
// The type 'T' not being passed in a function argument fixes it.
type Listener<T> = (e: T) => any
class EventEmitter<T> {
private listeners: Listener<T>[] = []
fire(data: T): void {}
}
class Node {
constructor(readonly graph: Graph<Node>, readonly data: string) {}
}
// Error: Property 'file' is missing in type 'Node' but required in type 'FileNode'.
class FileNode extends Node {
// Error: Type 'Graph<FileNode>' is not assignable to type 'Graph<Node>'.
constructor(readonly graph: Graph<FileNode>, readonly file: string, data: string) {
// Error: Argument of type 'Graph<FileNode>' is not assignable to
// parameter of type 'Graph<Node>'.
super(graph, data)
}
}
abstract class Provider<T extends Node> {
_onDidCreate = new EventEmitter<T>()
abstract setup(graph: Graph<T>): void
}
class Graph<T extends Node> {
// Replacing 'T' for 'any' here makes it work too,
// but that is obviously not a proper fix.
constructor(readonly provider: Provider<T>) {}
}
我计划像这样使用它,例如:
import * as vscode from "vscode"
// Error: Type 'FileNode' does not satisfy the constraint 'Node'.
export class VSCodeProvider extends Provider<FileNode> {
constructor(readonly root: string) {
super()
}
setup(graph: Graph<FileNode>) {
const watcher = vscode.workspace.createFileSystemWatcher(this.root)
watcher.onDidCreate((fileUri: vscode.Uri) => {
this._onDidCreate.fire(new FileNode(graph, fileUri.fsPath, "...data..."))
})
}
}
如何正确修复这些类型错误?我的一部分感觉这些错误通常只是一个糟糕的设计,所以如果有人建议如何通过更好的结构来解决这些错误,那就更好了。
每个节点都包含确定应该如何构建图的数据,例如应该建立哪些链接,但它只能在了解整个图的情况下这样做,因此需要访问图。我可以交换它并将一个节点传递给图表,但是一个节点需要的图表信息较少,然后一个图表需要一个节点来解决问题,所以这似乎是糟糕的设计。代码似乎受到高度耦合的提供者/图和节点/图的影响。
解决方案
您可以创建一个他们都实现的接口。然后你使用接口作为句柄。
export interface INode{}
export class Node implements INode {...}
export class FileNode implements IProvider {...}
export class VSCodeProvider extends Provider<INode> {...}
或者只是检查现有的类,如果它们有一个通用的接口。
推荐阅读
- android - 将日期和时间转换回毫秒
- python-3.x - 如何关闭在 Python/pythoncom/comtypes 中打开的 Windows 便携式设备 IStream
- raku - 有一个速记吗?
更多位置匹配多重签名中的类型 - php - 将带有 PHP 和 CURL 的 JSON 字符串发布到 php 页面并获得响应
- python - OpenStreetMap 背景上的 Cartopy 热图
- sql - SQL ISSUE - 查询计数帮助 + 分钟
- tensorflow - 这两种将皮尔逊相关性计算为损失函数的不同方法是否显着不同?
- php - 默认本地化语言文件不起作用
- python - 使用 Python 和 XlsxWriter 导出到 xlsx
- python - pandas 如何处理重复索引?