04
2017

TypeScriptの個人的tips

CATEGORYJavaScript
年末年始の貴重な休みを使い、何を思ったかTypeScriptでWebアプリを作っていて、とりあえず完成はしてないけど一段落したので、そこで得たtipsをまとめておく。
なお、tipsの使用例を見たい場合は↑のGitHubのソースを参照してください。

以下目次。今回はそんな大した話はない。
では、本文の方へ。


型も使えるJavaScriptとしてゆるく使う

一点目はTypeScriptを使う方針。TypeScriptは型チェックがちがちにするかとかコンパイルオプションとか tsconfig.json で決められるんだけど、個人的にはチェックは甘々にして、ゆるく使う方がいいと思った。
何故かというと、がちがちに使うと、既存のライブラリとか使うときが面倒くさすぎるから(汗

JavaScriptだと、伝統的に引数をオブジェクト型で貰う奴が多いと思うんだけど、がちがちにしてしまうとそういうとこでエラーが出まくって面倒。
型定義ファイルに不備があることもチラホラあるし、個人的にはそこまでがちがちにするのはJavaScriptの良さを殺してしまう気がするので、ゆるく使うのがよさげ。

というわけで、コンパイルオプションには noImplicitAny: false(暗黙のany型を許可)と suppressImplicitAnyIndexErrors: true(配列形式でのアクセスの場合型不一致でもエラーとしない)を指定しましょう。

引数/戻り値の型はきっちり書く

ゆるく使うと言いつつも、関数の引数/戻り値の型だけはきっちり書きましょう。
これだけは無いと型推論してくれなくなるし、IDEの補完も効かなくなるしでTypeScriptの利点が失われてしまう。
なので、I/Fになる部分の型だけはしっかりしましょう。

逆にいえば、I/Fになる部分以外はあんまり気にしなくてもデメリットない。

型定義ファイルは@typesで参照する

ライブラリの型定義ファイルの参照方法、調べると typings とか tsd とかいろいろ出てくるんだけど、TypeScript 2.0 からnpmコマンドだけで使える @types という仕組みが導入されてて、それを使うのが一番お手軽っぽいし公式っぽいのでおススメ。

ちなみに @types は dependencies の方に入れるのが正解らしいです。
(GitHubのどっかで見たコメント曰く、ライブラリの場合に呼び出し側でも型を参照できるようにするため。)

ただし、対応してないIDEもまだ多い模様。自分が最初(10月頃)使ってた NTVS では型が認識されず、VS Codeを試したら認識されたのでそっちに乗り換えたりと、ちょっとごたごたがあった。
TypeScriptの利点はIDEが型を認識してくれることだと思うので、認識されないと台無しなので、この辺は注意。

型に困ったらanyにキャスト

えー、なんかいろいろ最低なtipsな気がしますが、無理して型定義ファイルをがっちりやるより、困ったらもうanyにキャストして、ただの型のないJavaScriptコードとして書いてしまうのが手っ取り早いですはい。
内部処理とかだったら、別に困るわけでもなし。I/Fさえちゃんとしてれば、呼び出し側では型を活用できるし。

suppressImplicitAnyIndexErrors: true なら、オブジェクトにそんなプロパティねーよって言われたら、obj['key'] とか書いて誤魔化しましょう(酷

module.exports ≠ export default

Node.jsのモジュール形式の古いエクスポートとES2015のエクスポート構文、両者は微妙に動きが違うので、単純に置き換えるのはNG。
同じだと思って一括で置換してったりすると、なんかうまく参照できなくなってエラーになります。

同じくrequireとimportも微妙に動きが異なる(前者は動的で後者は静的?)。
気持ち悪いけど、なんか不都合があるなら無理して統一せず、古いライブラリはNode.js形式のままでとか使い分けましょう。

async/awaitは超絶便利

ES2017の先行実装的に搭載されている async/await が便利過ぎてヤバい。
例えば、今まで Promise を駆使して書いていた express の処理が、こんな感じにまるで普通の同期処理みたいに書ける。便利過ぎる。
router.delete('/:id', passportManager.adminAuthorize('super'), async function (req: express.Request, res: express.Response, next: express.NextFunction) {
try {
const admin = await Administrator.findById(validationUtils.toNumber(req.params['id']));
validationUtils.notFound(admin);
await admin.destroy();
res.json(admin);
} catch (e) {
next(e);
}
});
※ ソース全体はGitHub参照

例外投げたら普通に catch される。これまでの非同期処理の苦労からは考えられない(驚

欠点があるとしたら、先行実装なのでこの先仕様が変わらないか不安なことと、既存の Promise や callback の処理と混在するとちょっとごちゃごちゃするところ、かな。
Babelでも使えるらしいので、できればJavaScriptでも積極的に使いっていきたい。

なお、自分はあんま意識せず使い出したが、ライブラリとかが不要になって気軽に使えるようになったのは12月の2.1からとつい最近の事だった様子。


以上、こんなところか? TypeScript、最初はとっつきにくいなーと思ってたけど、自分の中で上のルールが定まってから&型定義ファイルが整ってきてからは、ガンガン補完されるしコンパイルでチェックされるしこれ使いやすー(感動 ってなってきたので、JavaScriptファックとか思ってる人は積極的に移行してみるといいよ。
スポンサーサイト

Tag: JavaScript TypeScript

0 Comments

Leave a comment