TypeScript のチュートリアルをやってみました



最近 TypeScript を導入しているとの話を多く聞くようになり、気になりつつも実際に触ったことがなかったので、TypeScript のチュートリアルをやってみました。





*TypeScript とは

大規模なWebアプリケーションのためにMicrosoftによって開発されたOSSのスクリプト言語で、TypeScript のソースコードをコンパイルすることで JavaScript のソースコードを生成します。
TypeScript 用の実行環境を用意しなくても JavaScript と同じ環境で動かすことができ、既存の JavaScript のコードも動かすことができます。
静的型付けをすることができるため、バグを早期に発見し生産性を向上させることができます。


*環境

  • MacOS
  • typescript 3.5.2


*参考



*TypeScript の実行

任意のディレクトリで下記コマンドを実行し、TypeScript をインストールします。
$ sudo npm install -g typescript

任意のディレクトリ配下にgreeter.tsを新規作成します。
この時点では、まだjavaScriptと同様のコードで書いています。
<greeter.ts>
function greeter(person) {
  return 'Hello, ' + person;
}

let user = 'Tom User';

document.body.innerHTML = greeter(user);

下記コマンドを実行してコンパイルします。
$ tsc greeter.ts

javaScript ファイルが生成されます。
<greeter.js>
function greeter(person) {
    return 'Hello, ' + person;
}
var user = 'Tom User';
document.body.innerHTML = greeter(user);


*型アノテーション

greeter()が呼び出されるときの引数が、文字列のみを受け付けるよう: stringを追加します。このように関数の引数の型を指定することを型アノテーションといいます。
今回はgreeter()の引数に文字列以外を指定して、エラーになることを確認してみます。
<greeter.ts>
// stringの型を追加
function greeter(person: string) {
  return 'Hello, ' + person;
}

// 文字列でなく数値のリストに変更
let user = [1, 100];

document.body.innerHTML = greeter(user);

コンパイルします。
$ tsc greeter.ts

greeter()の引数に、文字列以外の型が入ってきたのでエラーになります。
エラーになっても javaScript のファイルは生成されますが、意図した通りに動かないことを知らせてくれます。
greeter.ts:7:35 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

7 document.body.innerHTML = greeter(user);

Found 1 error.


*インターフェース

インターフェースを使って関数が実装すべき規約を定義することができます。下記ではgreeter()firstNamelastNameの文字列を持った引数のみを受け付けるようにしています。
明示的にimplements句を使わずに、インターフェースが必要とするメンバーを持ったオブジェクトを作成するだけでインターフェースを実装することができます。
<greeter.ts>
// インターフェースを追加
interface Person {
  firstName: string;
  lastName: string;
}

// 引数をインターフェースに変更
function greeter(person: Person) {
  return 'Hello, ' + person.firstName + '' + person.lastName;
}

// インターフェースのオブジェクトを作成
let user = { firstName: 'Tom', lastName: 'User' };

document.body.innerHTML = greeter(user);

コンパイルを実行します。
TypeScript のインターフェースはコンパイル時にのみ使用されるので、出力される JavaScript のコードにはインターフェースの情報は記述されません。
<greeter.js>
function greeter(person) {
    return 'Hello, ' + person.firstName + '' + person.lastName;
}
var user = { firstName: 'Tom', lastName: 'User' };
document.body.innerHTML = greeter(user);


*クラス

javaScript ES6 の新機能に含まれる、クラスを使ったオブジェクト指向での実装のサポートもしています。
クラスのコンストラクタに型とアクセス修飾子を使うことができます。インターフェースを実装している場合、インターフェースと同じ名前のメンバーが存在している必要があります。また、インターフェースのメンバー全てがpublicとなります。
下記ではStudentクラスのコンストラクタで、インターフェースで定義したfirstName/lastNameと、middleInitialとする文字列を受け取るように指定しています。インターフェースは最低限必要なメンバーを持ったオブジェクトであれば良いので、middleInitialとする文字列が追加で存在していても問題ないです。
<greeter.ts>
// クラスを追加
class Student {
  fullName: string;
  constructor(public firstName: string, public middleInitial: string, public lastName: string) {
    this.fullName = firstName + '' + middleInitial + '' + lastName;
  }
}

interface Person {
  firstName: string;
  lastName: string;
}

function greeter(person: Person) {
  return 'Hello, ' + person.firstName + '' + person.lastName;
}
// 今回は使わない
let user = { firstName: 'Tom', lastName: 'User' };

// Studentのインスタンスを作成
let member = new Student('Tom', 'M.', 'User');

// 引数をStudentクラスに修正
document.body.innerHTML = greeter(member);

コンパイルすると下記の javaScript ファイルが作成されます。
<greeter.js>
var Student = /** @class */ (function () {
    function Student(firstName, middleInitial, lastName) {
        this.firstName = firstName;
        this.middleInitial = middleInitial;
        this.lastName = lastName;
        this.fullName = firstName + '' + middleInitial + '' + lastName;
    }
    return Student;
}());
function greeter(person) {
    return 'Hello, ' + person.firstName + '' + person.lastName;
}
var user = { firstName: 'Tom', lastName: 'User' };
var member = new Student('Tom', 'M.', 'User');
document.body.innerHTML = greeter(member);


*ブラウザで表示

HTMLファイルgreeter.htmlを新規作成し、コンパイル後の javaScript ファイルを読み込むようにします。
<greeter.html>
<!DOCTYPE html>
<html>
  <head>
    <title>TypeScript Greeter</title>
  </head>
  <body>
    <script src="greeter.js"></script>
  </body>
</html>

HTMLファイルをブラウザで表示すると、document.body.innerHTMLに設定したgreeter()の値が表示されます。












*所感

業務で Java を使っていた経験があるので、インターフェースや型の指定については馴染みやすかったです。
javaScript は簡単に書ける反面、後から見て変数に何の値が入ることを想定しているのかわかりづらかったりしたので、型を定義したほうが保守性が上がると感じました。
React や Vue といったフレームワークも TypeScript をサポートしているので、今後拡大する予定のWebアプリケーションに後から TypeScript を導入するとメリットが多く得られるかと思いました。

Previous
Next Post »

人気の投稿