如何通过自定义Apollo GraphQL解析器用sequelize-typescript查询关联对象并解决TS报错
基于Apollo GraphQL + sequelize-typescript 关联查询的TypeScript适配方案
报错核心原因
出现event.$get('user')无法被TypeScript识别的问题,通常是两个原因叠加导致:
- 模型双向关联声明不完整:仅在User模型上声明了对Event的HasOne关联,未在Event模型上声明对应的BelongsTo关联,sequelize-typescript无法生成对应的类型映射
- 解析器入参缺少类型标注:TS无法自动推导
event参数的类型是Event模型实例,自然匹配不到实例上的$get方法
修正步骤
1. 补全双向关联的模型定义
按照实际关联关系,在两个模型上完成对应装饰器声明:
- 单条Event归属于单个User:在Event模型上通过
@BelongsTo装饰器声明user关联字段 - 单个User持有对应Event:在User模型上通过
@HasOne装饰器声明event关联字段
补全后的模型代码示例:
// event.model.ts import { BelongsTo, Model, Table } from 'sequelize-typescript'; import User from './user.model'; @Table({ timestamps: false, modelName: 'Event' }) export default class Event extends Model { @BelongsTo(() => User) user: User; }
// user.model.ts import { HasOne, Model, Table } from 'sequelize-typescript'; import Event from './event.model'; @Table({ timestamps: false, modelName: 'User' }) export default class User extends Model { @HasOne(() => Event) event: Event; }
2. 为解析器入参添加类型标注
将解析器中无类型标注的event参数,明确指定为Event模型的实例类型,此时TS可以自动识别实例上的$get方法,还会对传入的关联名做类型提示,避免写错关联名。
修正后的解析器代码:
import Event from './event.model'; import User from './user.model'; static resolver() { return { Event: { user: async (event: Event): Promise<User> => { return event.$get('user'); } } } }
3. 兼容兜底方案
如果因sequelize-typescript版本兼容问题,依然无法识别$get方法的类型,可以通过类型断言明确方法签名,消除TS报错:
user: async (event: Event): Promise<User> => { return (event.$get as (association: 'user') => Promise<User>)('user'); }
内容的提问来源于stack exchange,提问作者Eugene Zalivadnyi
相关产品推荐
相关产品推荐

