【发布时间】:2020-07-31 03:11:01
【问题描述】:
我对 Deno 中的 TypeScript 泛型有疑问。
abstract class Packet {
public abstract read(): Uint8Array;
public abstract write(data: Uint8Array): void;
}
type PacketData = Packet | Uint8Array;
type HookCallbackResult<T extends PacketData> = T | null | undefined;
type HookCallback<T extends PacketData> = (data: T) => HookCallbackResult<T>;
interface HookCallbackInfo<T extends PacketData> {
packetType: typeof Packet | "any";
callback: HookCallback<T>;
}
let callbacks: HookCallbackInfo<PacketData>[] = [];
function hook<T extends PacketData>(packetType: typeof Packet | "any", callback: HookCallback<T>) {
callbacks.push({ packetType, callback });
// ^^^^^^^^
// error: TS2322 [ERROR]: Type 'HookCallback<T>' is not assignable to type 'HookCallback<PacketData>'.
// Types of parameters 'data' and 'data' are incompatible.
// Type 'PacketData' is not assignable to type 'T'.
// 'PacketData' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
// Type 'Packet' is not assignable to type 'T'.
// 'Packet' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
}
我的目的是强制作为第二个参数传递给 hook 函数的回调返回与其参数相同类型的结果 OR null OR undefined 并且此类型应该是 Uint8Array 或已经解析Packet(或其子类),仅此而已。并且hook 函数应该存储这个钩子回调以供进一步使用。 Deno 的 TypeScript 编译器版本在向对象(使用接口 HookCallbackInfo 声明)数组添加回调时出现恐慌。
我想我在泛型的某个地方犯了一个错误,因为我无法正确理解它们如何在 TypeScript 中使用这些多种类型定义(例如 Type1 | Type2 | Type3)。你能解释一下我到底做错了什么以及如何以正确的方式做我想做的事吗?
【问题讨论】:
标签: typescript generics deno