Docker环境构建Node.js应用遇TS2322类型不兼容错误求助
问题
在Docker环境下构建Node.js应用,执行命令npx nx build driver-api --prod时出现TS2322类型错误,错误日志如下:
=> ERROR [build 7/7] RUN npx nx build driver-api --prod 53.9s ------ > [build 7/7] RUN npx nx build driver-api --prod: nx run driver-api:build:production chunk (runtime: main) main.js (main) 348 KiB [entry] [rendered] ERROR in /app/libs/database/src/lib/redis-pub-sub.provider.ts ./libs/database/src/lib/redis-pub-sub.provider.ts 16:10-19 [tsl] ERROR in /app/libs/database/src/lib/redis-pub-sub.provider.ts(16,11) TS2322: Type 'Redis' is not assignable to type 'RedisClient'. Type 'Redis' is missing the following properties from type 'Redis': stream, isCluster, connector, reconnectTimeout, and 140 more. ERROR in /app/libs/database/src/lib/redis-pub-sub.provider.ts ./libs/database/src/lib/redis-pub-sub.provider.ts 17:10-20 [tsl] ERROR in /app/libs/database/src/lib/redis-pub-sub.provider.ts(17,11) TS2322: Type 'Redis' is not assignable to type 'RedisClient'. ERROR in libs/database/src/lib/redis-pub-sub.provider.ts:16:11 TS2322: Type 'Redis' is not assignable to type 'RedisClient'. Type 'Redis' is missing the following properties from type 'Redis': stream, isCluster, connector, reconnectTimeout, and 140 more. #12 53.66 14 | }; #12 53.66 15 | return new RedisPubSub({ #12 53.66 > 16 | publisher: new Redis(options), #12 53.66 | ^^^^^^^^^ #12 53.66 17 | subscriber: new Redis(options), #12 53.66 18 | }) #12 53.66 19 | } , #12 53.66 #12 53.66 ERROR in libs/database/src/lib/redis-pub-sub.provider.ts:17:11 #12 53.66 TS2322: Type 'Redis' is not assignable to type 'RedisClient'. #12 53.66 15 | return new RedisPubSub({ #12 53.66 16 | publisher: new Redis(options), #12 53.66 > 17 | subscriber: new Redis(options), #12 53.66 | ^^^^^^^^^^ #12 53.66 18 | }) #12 53.66 19 | } , #12 53.66 20 | }; #12 53.66 #12 53.66 webpack compiled with 4 errors (b984ccb820b8363c)
对应的redis-pub-sub.provider.ts代码:
import { pubSubToken } from '@nestjs-query/query-graphql'; import { RedisPubSub } from 'graphql-redis-subscriptions'; import Redis from 'ioredis'; import { Provider } from '@nestjs/common'; export class RedisPubSubProvider { static provider(): Provider { return { provide: pubSubToken(), useFactory: () => { const options = { host: process.env.REDIS_HOST || 'localhost', port: 6379 }; return new RedisPubSub({ publisher: new Redis(options), subscriber: new Redis(options), }) } , }; } }
错误核心提示:Type 'Redis' is not assignable to type 'RedisClient'
解决方案
原因分析
graphql-redis-subscriptions的RedisPubSub默认依赖node-redis(redis包)的客户端类型,而当前使用的是ioredis包的客户端,两者类型定义不兼容,导致TypeScript编译报错。
方法1:改用node-redis替代ioredis
如果没有必须使用ioredis的场景,直接切换到node-redis:
- 卸载ioredis并安装redis包:
npm uninstall ioredis && npm install redis
- 修改
redis-pub-sub.provider.ts代码:
import { pubSubToken } from '@nestjs-query/query-graphql'; import { RedisPubSub } from 'graphql-redis-subscriptions'; import { createClient } from 'redis'; import { Provider } from '@nestjs/common'; export class RedisPubSubProvider { static provider(): Provider { return { provide: pubSubToken(), useFactory: () => { const options = { host: process.env.REDIS_HOST || 'localhost', port: 6379 }; return new RedisPubSub({ publisher: createClient(options), subscriber: createClient(options), }) } , }; } }
方法2:使用RedisAdapter适配ioredis(保留ioredis)
如果需要继续使用ioredis,利用graphql-redis-subscriptions提供的适配器做类型转换:
- 修改
redis-pub-sub.provider.ts代码:
import { pubSubToken } from '@nestjs-query/query-graphql'; import { RedisPubSub, RedisAdapter } from 'graphql-redis-subscriptions'; import Redis from 'ioredis'; import { Provider } from '@nestjs/common'; export class RedisPubSubProvider { static provider(): Provider { return { provide: pubSubToken(), useFactory: () => { const options = { host: process.env.REDIS_HOST || 'localhost', port: 6379 }; const redisClient = new Redis(options); return new RedisPubSub({ publisher: new RedisAdapter(redisClient), subscriber: new RedisAdapter(redisClient), }) } , }; } }
方法3:类型断言(临时应急方案)
不推荐长期使用,仅作为临时绕过编译错误的方式:
- 先导入
RedisClient类型,再通过类型断言强制转换:
import { pubSubToken } from '@nestjs-query/query-graphql'; import { RedisPubSub, RedisClient } from 'graphql-redis-subscriptions'; import Redis from 'ioredis'; import { Provider } from '@nestjs/common'; export class RedisPubSubProvider { static provider(): Provider { return { provide: pubSubToken(), useFactory: () => { const options = { host: process.env.REDIS_HOST || 'localhost', port: 6379 }; return new RedisPubSub({ publisher: new Redis(options) as unknown as RedisClient, subscriber: new Redis(options) as unknown as RedisClient, }) } , }; } }
内容的提问来源于stack exchange,提问作者intellizetm
相关产品推荐
相关产品推荐

