TypeScript如何通过泛型提取类实例类型实现GraphQL订阅参数校验
解决方案
问题根源
你当前写法里typeof Subscriptions[T]['event'] 获取的是类构造函数本身的类型,匹配的是类的静态属性(比如name、length),而非类实例的成员属性。
修复方案
TypeScript 内置了InstanceType<T>工具类型,专门用于提取构造函数类型对应的实例类型,你只需要把入参data的类型用InstanceType包裹即可:
const publishSubscription = <T extends keyof typeof Subscriptions>( name: T, data: InstanceType<typeof Subscriptions[T]['event']> ) => { // TODO: implement };
可选优化:给配置加统一类型约束
为了避免后续新增订阅配置时写错字段结构,可以先给Subscriptions对象加统一的类型约束:
// 先定义订阅配置的通用结构 type SubscriptionConfig = { name: string; // 约束event字段为类构造函数 event: new (...args: any[]) => any; channelName: string; }; // 给Subscriptions加类型约束 export const Subscriptions: Record<string, SubscriptionConfig> = { conversationCreated: { name: 'onConversationCreated', event: ConversationCreatedEvent, channelName: 'CONVERSATION_CREATED', }, // 后续新增其他订阅配置会自动校验结构 };
效果验证
调用方法时会自动匹配对应订阅的实例结构校验:
// 校验通过 publishSubscription('conversationCreated', { conversationID: 'conv_123', userID: 'user_456' }); // 类型报错:缺少userID字段 publishSubscription('conversationCreated', { conversationID: 'conv_123' }); // 类型报错:conversationID类型不匹配 publishSubscription('conversationCreated', { conversationID: 123, userID: 'user_456' });
内容的提问来源于stack exchange,提问作者Nickersoft
相关产品推荐
相关产品推荐

