前提
- TypeScript 1.8
背景
TypeScriptの型定義やモジュール周りの書き方・設定はなんだかよくわからない部分が多いです。いくつかのサンプルコードを見るとノリで書けそうだけど、結局ハマってしまいました。
ハマってしまった部分を中心にざっくり、かつできるだけ具体的にまとめます。
英語が読める人はこの記事を読むよりも、ハンドブックの最初からじっくり読んだ方がいいと思います。
クラスを定義して読み込む方法
class
まず、普通にクラスを定義する書き方はこうです。
class Greeter {
public hello() {
console.log('hello');
}
}
exportとimport
では、他のファイルからimportして使いたいときにどう書けばいいでしょうか。こう書けばいいです。
export class Greeter {
public hello() {
console.log('hello');
}
}
import {Greeter} from './hello-world';
let greeter = new Greeter();
greeter.hello(); // hello
default
defaultというキーワードを使うとこんな感じに書けます。
export default class Greeter {
public hello() {
console.log('hello');
}
}
import MyGreeter from './hello-world';
let greeter = new MyGreeter();
greeter.hello(); // hello
defaultを指定してあげたので、先ほどのように「hello-world.ts
からどれをimportするか」という指定(先の例だとGreeter)が不要になりました。
ここで、Greeterというクラスを使うときにMyGreeterという名前で使っていますので、先程のimport {Greeter}
とは意味が違うことが分かるかと思います。要は、以下と等しい。
import {Greeter} as MyGreeter from 'hello-world';
モジュールを定義して読み込む方法
状態を持たない・インスタンスを作らない関数群をまとめておきたいだけの時もあるので、全てをクラスとして定義するわけにもいきません。Rubyで言うところの以下のようなものを書きたいと思いました。
module HelloWorld
extend self
def hello
puts :hello
end
end
require "./hello_world"
HelloWorld.hello #=> :hello
export function
export function hoge() {}
のように関数群を書いて、それをimportすればいいです。気持ち的にnamespace
とかmodule
で区切ってあげなきゃいけないんじゃないの...?と思いたくなりますが、そんなこと無いようです。
export function hello() {
console.log('hello');
}
export function goodBye() {
console.log('good bye.');
}
上のように書いて、以下のように使えます。
import {hello} from './hello-world';
hello();
あるいは、モジュールごと全部読んでもいい。
import * as HelloModule from './hello-world';
HelloModule.hello();
モジュールの補足: TypeScript 1.8 以降 と use strict
export function() {}
を書いたらTSLintに怒られました。
tslint.jsonを見ると、たしかにその設定が書かれていました。
"use-strict": [true, "check-module", "check-function"]
TypeScriptは1.8から use strictを自動で付加してくれるようになっているので、この設定は要りません(当該プロジェクトでこの設定が書かれたのは1.5.0beta時代でした)。
TypeScriptの型定義
型定義にまつわる何かを書いていきます。
型定義ファイルとDefinitelyTyped
DefinitelyTypedというところにある型定義ファイルをインストールして使えば大丈夫です。
typings install dt~jquery --save --global
基本的にTypeScriptで Node Modules を使う場合、 npm install したら typings install することになるかと思います。TypeScript 2.0 からは@types
というのを使うそうですが、よく知りません。
interface Window の拡張
たとえばGoogle Analyticsのような外部スクリプトを使う場合、そのスクリプトの関数はwindow
オブジェクトに生やされます。しかし、これを参照しようとするコードをTypeScriptで書くと怒られます。
じゃあどうすればいいのかというと、このインタフェースを拡張することになります。
declare global {
interface Window {
ga?: () => void;
}
}
これで、window.ga
を参照するコードを書いても怒られません。
まだよく理解してない部分があるような気がするので、書き足したり書き直したりしていきます。