- はじめに
- TypeScriptはいいぞ
- TypeScriptって何よ?JavaScriptとどう違うの?
- TypeScript で開発されているもの
- TypeScriptのいいところ
- 実際にTypeScriptを書いてみる
- TypeScript で CLI アプリケーションを作る
- さいごに
はじめに
この記事は CCS Advent Calendar 2020の15日目の記事です。
えびてんくんの記事: 土鍋による炊飯←前|次→でんちゅらくんの記事: 冬にはオススメ出来ない都内の歩き方
TypeScriptはいいぞ
突然ですが弊サークルでは新入生にはC言語を教えることが多いです。C言語だったりC++を使ってWindowsアプリケーションとしてゲームを作っている会員がほとんど。自分もC++好きです。闇もありますが楽しい言語ですよね。
ところが最近、ぼくはC++から離れてしまっています。というのも、普段のアルバイトだとか研究だとかで主にいじっているのがWebアプリケーションなため。C++でもWebAssenblyとかあるけど、基本的にはWebアプリケーションをつくるのにC++を選択する人はそういないんじゃないですかね。(サーバー部分だけとかはあるだろうけれど......)
Web系の言語だと多くの人が思い浮かべるのはそう、JavaScriptだと思います。当然ぼくもWebApp周り触るにあたってJavaScriptを触るわけなんですが.....、気分が悪くなってきました。普段からクラスベースで開発して、静的型付け言語ばかり触ってきた身には呼吸が大変しづらいです。
そこで!!TypeScriptの出番です。
TypeScriptって何よ?JavaScriptとどう違うの?
TypeScriptはJavaScriptのスーパーセット、強化版。これだけで強そう。 JavaScriptに対して静的型付けとクラスベースのオブジェクト指向をとりいれたものがTypeScriptで、JavaScriptアプリケーションの開発が可能です。なんと開発元は天下のMicrosoft。
仕組みはかんたんで、JavaScriptの文法を強化したTypeScriptファイルを記述したあと、TypeScriptコンパイラがJavaScriptファイルに変換してくれます。コンパイルというけれど、やっていることはコードの変換なのでトランスコンパイル。
こんなかんじ。TypeScriptで書いたもののほうがC++erには馴染み深い感じがするのではないでしょうか?
TypeScript で開発されているもの
ぼくもだいすきVSCode、TypeScriptで開発されています。確認したらコードの実に93.7%がTypeScriptでした。
TypeScriptのいいところ
型付けができる
まずコレを見てください。
let str="hello"; str=123;
JavaScript、これが許されます。は? いやまあそういうものなのだけれど......。TypeScriptならこんなことは"ちゃんと"できません!!頑張ってやろうとするなら
let str: string | number = "hello" str=123
と二種類の型を取ることを明示することで不明瞭な感じを排除できます。これはうれしい!一発でstr
がstring
型かnumber
型のどちらかであることがわかりますね(変数名の話はここではおいておいて)。
さて、これ変数の型でも嬉しいですが、特に顕著なのが関数に渡す値の型や返ってくる値の型が明瞭なところです。
function add(a, b) { return a + b } const ans = add(x, y)
こんなコードがあったとする。このコードのadd()
関数、渡す引数が数値でなくて文字列でもうまく動いてしまいます。でもこの関数を作った人はそんなことは想定していないかもしれません。そこでTypeScriptを使うと
function add(a: number, b: number) { return a + b }
これならこの関数の引数がnumber
であることも丸わかり、なんなら返り値までnumber
であることが保証されます。すばらしい!!!JavaScriptあるあるだと思うんですが、この渡すものが構造体的な大きなものになってくるとどんどん怪しくなってくるんですよね......それが防止できます。
さらに言えばちゃんとしたエディタならこれらのことからエラーチェックもできるようになるんですよね。実行時エラー防止!
クラスを使える
コレは少し語弊があって、JavaScriptでもクラスは使えるんですが......(ES6以降class構文が導入された)、JavaScriptのクラスっぽい何か、C++とかやっていた身からすると使いづらくないですか?TypeScriptを導入することですんなりとクラスを使うことができます。やったー!
トランスコンパイルのパワー
TypeScriptはそのコードから変換することでJavaScriptを生成します。つまりその変換先のJavaScriptをコントロールできるということになります。最新のTypeScriptコードから、変換先のJavaScriptを古いものにすれば古い環境でも動かすことができる!すごい!
JavaScriptも動く
警告等は出ますが、JavaScriptのコードをTypeScriptとしてベタ貼りしても動かすことができます。つまり今までのJavaScriptをTypeScriptに移行するのも一気にやる必要がないですね!
実際にTypeScriptを書いてみる
このへんはぐぐったら似たような記事たくさん出てきそう。雑にいきます。「Node.js」ってやつを使います。
環境構築
とりあえずNode.jsで検索してダウンロードしてインストールしましょう。homebrew
とかapt
とかでもあります。さて、node.jsがインストールしおわったら、npm
というコマンドが使えるようになっているんじゃないでしょうか。
npm
はnode.jsのパッケージマネージャです。プログラムを書いていると、他の人が作ったライブラリとかを使うこともあると思います。このへんをよしなに導入してくれるすごいやつです。とはいえ、このnode.jsのパッケージマネージャはnpm
以外にもあって、ぼくはyarn
ってのを使っています。
ってことでyarn
が使える前提で話を進めていきます。
$ mkdir hello-typescript
$ yarn init
適当なところに練習用のディレクトリを作成して、そこでyarn init
コマンドを実行します。いろいろ聞かれるので適当に答えていくとpackage.json
が生成されます。ここにはライブラリの情報とかもはいっているので、gitとかから同じものをDLした人は、yarn install
するだけで自動で環境構築されます。便利。Pythonのpipenv
みたいなやつよね。
これでNode.jsを使ってJavaScriptを書くことができるようになりました。とはいえ、まだTypeScriptが書けないのでかけるようにします。
$ yarn add typescript @types/node
$ yarn run tsc --init
次にpackage.json
を開いてyarn
が勝手にコンパイル&実行までしてくれるコマンドを記述。tsc -p .
でTypeScriptファイルをコンパイルしてnode .
で実行。
{ (略) "scripts": { "start": "tsc -p . && node ." }, (略) }
これで準備OK。あとは適当にindex.ts
を作って
const str: string = "Hello TypeScript!" console.log(str)
実行してあげると
$ yarn run start
Hello TypeScript!
うまく実行できて、index.js
ファイルも生成されていることがわかる。ちなみに
$ yarn add ts-node
とts-node
をインストールして
{ (略) "scripts": { "start": "ts-node ." }, (略) }
とするとjsファイルを残さずに一気に実行までやってくれる。ts-node
便利。
これで好きにTypeScriptがかけるようになりました!
TypeScript で CLI アプリケーションを作る
これはおまけなんですが、せっかくTypeScriptがかけるようになったのでなんか作ってみます。TypeScriptはJavaScriptの強化版なので、JavaScript用にライブラリが出ていれば使うことができます。そして世の中はJavaScript向けにライブラリを提供しているもので溢れています。今回はGoogleさんの力を借りてみることとします。ちょっとCloud Vision APIで遊んでみようかなって。
はじめるまえにライブラリのインストール
yarn
さんがいるので一瞬です。コマンドラインで入力するので、引数のパーサーもいれておきます。Pythonのargparseとだいたい同じやつです。
$ yarn add @google-cloud/vision argparse
$ yarn add -D @types/argparse
使うライブラリのドキュメントたち↓
コードを書く
書くだけ。
index.ts
import { ArgumentParser } from "argparse" import { VisionApi } from "./lib/google/VisionApi" async function main() { const parser = new ArgumentParser({ description: 'Text Detection (Google Cloud Vision API - OCR -)', add_help: true }) parser.add_argument('-p', '--path', {help: "image file path or URL", required: true}) const args = parser.parse_args() const va = new VisionApi() va.detectText(args.path) } main()
これTypeScriptすごい!ポイントなんですけど、ArgumentParser
の引数とかadd_argument
の引数で複数の値の塊渡す時にちゃんと型の補完が入ってくれるんですよね。なので実行時に型が実は違った!みたいなエラーを回避できます。嬉しい。
VisionApi.ts
import { ImageAnnotatorClient } from "@google-cloud/vision" export class VisionApi { async detectText(fileName: string) { const client = new ImageAnnotatorClient() const [ result ] = await client.textDetection(fileName) const detections = result.textAnnotations console.log('Text: ') detections?.forEach( text => { console.log(text.description) }) } }
実行
画像から文字を抽出してくれます。精度はそれなり。手書きはきつそう。
$ gcloud auth login
$ yarn run start
よく見たら紙の「Date」正確に読み取ってて笑った。
作ったやつ
ちょっとあとからコマンド追加できたりするように調整してあるよ。
さいごに
TypeScriptの紹介とおまけはこれでおわり!みんなもぜひTypeScript触ってみてね!
ちなみにTypeScriptでデスクトップアプリもつくれます(VSCodeがまさにそう)。TypeScriptとHTMLとCSSを組み合わせてUIを作れたりするので、TypeScriptでゲームを作ってみたりするのも面白い......かも?