如何在TypeScript中基于关联泛型Payload生成具体类实例?
TypeScript 基于Payload的
kind字段创建对应Packet实例及后续处理器实现 我需要接收一个泛型Payload对象,根据它的kind字段创建对应具体类型的类实例,这应该可以用*关联类型(correlated types)*实现,但我还没掌握用法。因为要处理20多种kind类型,所以希望用映射方式实现,不想写一堆if...else和类型守卫。
测试代码
// 测试Payload(模拟从JSON解析后转为IPayload类型) const alphaPayload = { kind: 'alpha', alpha: 'a' } as IPayload; const betaPayload = { kind: 'beta', beta: 1 } as IPayload; // 预期:alphaPacket和betaPacket分别为AlphaPacket和BetaPacket类型 const alphaPacket = PacketDecoder.decodePacket(alphaPayload); const betaPacket = PacketDecoder2.decodePacket(betaPayload); console.log(alphaPacket.getKind(), alphaPacket.getAlpha()); console.log(betaPacket.getKind(), betaPacket.getBeta());
已尝试的实现方式
// Payload定义 interface IPayload { kind: string; } interface AlphaPayload extends IPayload { kind: 'alpha'; alpha: string; } interface BetaPayload extends IPayload { kind: 'beta'; beta: number; } // Packet定义 interface IPacket { getPayload(): IPayload; getKind(): IPayload['kind']; } class Packet<T extends IPayload> implements IPacket { constructor(protected payload: T) {} getPayload(): T { return this.payload; } getKind(): T['kind'] { return this.payload.kind; } } class AlphaPacket extends Packet<AlphaPayload> { getAlpha(): string { return this.payload.alpha; } } class BetaPacket extends Packet<BetaPayload> { getBeta(): number { return this.payload.beta; } } // 类型映射 const kindToPacket = { alpha: AlphaPacket, beta: BetaPacket } as const; type KindMap = typeof kindToPacket; type KindKey = keyof KindMap; type KindToPacketConstructor<K extends KindKey = KindKey> = { [P in K]: KindMap[P] }[K] type KindToPayload<K extends KindKey = KindKey> = { [P in K]: ConstructorParameters<KindMap[P]>[0] }[K] // 类型守卫 function isValidKind(kind: string): kind is KindKey { return kind in kindToPacket; } function isValidPayload(payload: IPayload): payload is KindToPayload { return payload.kind in kindToPacket; } // 尝试实现1 class PacketDecoder { static decodePacket<T extends IPayload>(payload: T): Packet<T> { if (isValidKind(payload.kind)) { const PacketClass = kindToPacket[payload.kind]; return new PacketClass(payload); // 此处类型不匹配,存在问题 } throw new Error(`Unknown ${payload.kind}`); } } // 尝试实现2 class PacketDecoder2 { static decodePacket(payload: IPayload) { if (isValidPayload(payload)) { return PacketDecoder2.makePacket(payload.kind, payload); } throw new Error(`Unknown ${payload.kind}`); } static makePacket<K extends KindKey>(kind: K, payload: KindToPayload<K>) { const PacketClass: KindToPacketConstructor<K> = kindToPacket[kind]; return new PacketClass(payload); // 此处类型推导存在问题 } }
后续需求
接下来我要定义一个PacketHandler类,希望它能接收decodePacket的结果,自动传递给对应的处理函数,比如handleAlpha(packet: AlphaPacket)和handleBeta(packet: BetaPacket)。
内容的提问来源于stack exchange,提问作者brightemo
相关产品推荐
相关产品推荐

