TypeScript と ioredis のソースコード
TypeScript で Redis 使いたい場合は ioredis で書いてこんな感じのコードになる。
sample.ts
import * as Redis from 'ioredis'; (async () => { const redis = new Redis(); const pong = await redis.ping(); // => PONG })();
Jest のテストコード
ところが Jest でテスト書いたら実行できなくてハマってしまった。
sample.spec.ts
import * as Redis from 'ioredis'; describe('Redis', () => { it('should be return pong', async () => { const redis = new Redis(); const pong = await redis.ping(); redis.disconnect(); expect(pong).toBe('PONG'); }) });
.ts
ファイルを直接実行するので ts-jest を入れている。
$ jest TypeError: Redis is not a constructor 4 | 5 | it('should be return pong', async () => { > 6 | const redis = new Redis(); | ^ 7 | const pong = await redis.ping(); 8 | redis.disconnect(); 9 | expect(pong).toBe('PONG'); at Object.it (src/sample.spec.ts:6:19)
TypeError: Redis is not a constructor
なんでやねん
import * as Redis from 'ioredis'; const redis = new Redis();
のところでコンストラクタじゃないと言われる。書き方は正しいのに。
import Redis from 'ioredis';
に直したら動いた。間違ってるのに。
まぁそんなこともあるのかなと思ったりもしたけど、テストファイルをコンパイルして .js
ファイルにしてテスト実行してみるとエラーになる。
TypeError: ioredis_1.default is not a constructor 4 | describe('Redis', () => { 5 | it('should be return pong', async () => { > 6 | const redis = new ioredis_1.default(); | ^ 7 | const pong = await redis.ping(); 8 | redis.disconnect(); 9 | expect(pong).toBe('PONG'); at Object.it (dist/sample.spec.js:6:23)
TypeError: ioredis_1.default is not a constructor
やっぱり書き方が間違ってるいるわけだ。
原因
ts-jest
にバグがあったようだ。
"devDependencies": { "@types/ioredis": "^4.0.3", "@types/jest": "^23.3.5", "jest": "^23.6.0", "ts-jest": "^21.2.4", "typescript": "^3.1.3" }
yarn upgrade --latest ts-jest
して 23.10.4
にしたら治った。