あいつの日誌β

働きながら旅しています。

TypeScript で callback しようとしたらエラーになって悩んだ

どうした?

とりあえず環境を用意します

% mkdir practice-ts-callback && cd $_
% tslint init
% npm init --yes
% npm install co --save
% dtsm init
% dtsm install node --save

ひとまず compilerOptions は以下のようにします。

create tsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "noImplicitAny": true,
  }
}

create bootstrap.ts:

/// <reference path="typings/bundle.d.ts" />

const cb = (hasError: boolean, callback: (err?: Error) => void): void => {
  if (hasError) {
    return callback(new Error("omg"));
  }
  callback();
};

cb(false, (err) => {
  console.log(err);
});

cb(true, (err) => {
  console.log(err);
});

実行結果

% ts-node bootstrap.ts                                                                                   
undefined
[Error: omg]

それで?

cb を 外部モジュールに持って行きます。

create cb.ts

/// <reference path="typings/bundle.d.ts" />
const cb = (hasError: boolean, callback: (err?: Error) => void): void => {
  if (hasError) {
    return callback(new Error("omg"));
  }
  callback();
};

export = cb; 

edit bootstrap.ts:

/// <reference path="typings/bundle.d.ts" />
const cb = require("./cb");

cb(false, (err) => {
  console.log(err);
});

cb(true, (err) => {
  console.log(err);
});

そうするとこうなってしまう

% ts-node bootstrap.ts
----------------------------------
⨯ Unable to compile TypeScript

bootstrap.ts (4,12): Parameter 'err' implicitly has an 'any' type. (7006)
bootstrap.ts (8,11): Parameter 'err' implicitly has an 'any' type. (7006)
----------------------------------

なんでなん?

これはどうやら "noImplicitAny": true だとそういう挙動をするみたいです。

とりあえず以下のようにすると動きます。

const cb = require("./cb");

cb(false, (err?: Error) => {
  console.log(err);
});

cb(true, (err?: Error) => {
  console.log(err);
});

実行結果

% ts-node bootstrap.ts                                                                                   
undefined
[Error: omg]

おしまい