Edited at

TypeScriptのimport指定方法

More than 5 years have passed since last update.

TypeScriptで作成した State Monadをモジュールにしてみた。

importの指定に、若干迷いましたので共有します。


今回の目標

TypeScriptのモジュール化を行う。


モジュールの配置

State Monadモジュールは、ファイル名stateMonad.tsとし、root/monad/state/stateMonad.tsに配置する。

Stackモジュールは、ファイル名stack.tsとし、root/stack/stack.tsに配置する。

テストモジュールは、ファイル名stackTest.tsとし、root/stackTest.tsに配置する。


State Monadモジュール


root/monad/state/stateMonad.ts

export

module monad.state {
export
interface Tuple2<A,B> {
fst: A
snd: B
}
export
class State<T,X>{
runState: (t:T) => Tuple2<X,T>
evalState = (t:T):X => this.runState(t).fst
execState = (t:T):T => this.runState(t).snd
constructor(g:(t:T) => Tuple2<X,T>){
this.runState = g
}
static returns<T,X>(v:X):State<T,X>{
return new State<T,X>((t:T) => { return {fst:v, snd:t } })
}
bind<B>(f: (x:X) => State<T,B>):State<T,B>{
var g = (t:T) => {
var st = this.runState(t)
return f(st.fst).runState(st.snd)
}
return new State<T,B>(g)
}
}
export
class MonadState {
static get<T>():State<T,T> {
var g = (t:T) => {
return { fst: t, snd: t }
}
return new State<T,T>(g)
}
static put<T>(a:T):State<T,void> {
var g = (t:T) => {
return { fst: null, snd: a }
}
return new State<T,void>(g)
}
}
}

モジュールとして外部に提供するmoduleclassにはexportを付加した。

Tuple2は本来なら別モジュールとするべきだが、今回はこのモジュールに含めた。


Stackモジュール


root/stack/stack.ts

import ms = require("../monad/state/stateMonad")

export
module stack {
export
class Stack<X> {
pop = <X>():ms.monad.state.State<X,X[]> =>
ms.monad.state.MonadState.get<X[]>()
.bind((e:X[]) => {
return ms.monad.state.MonadState.put<X[]>(e.slice(1))
.bind(k => ms.monad.state.State.returns(e[0])) })

push = <X>(i:X):ms.monad.state.State<X,void> =>
ms.monad.state.MonadState.get<X[]>()
.bind((e:X[]) =>
ms.monad.state.MonadState.put<X[]>([i].concat(e)))
}
}


外部モジュールのstateMonad.tsを使用するため、importが必要。

requireはこのモジュールからの相対パスを指定する。

また、外部モジュールを使用する際は、importに使用したms.にフォルダ名monad.state.を付加して使用する。


テストモジュール


root/stackTest.ts

import ms = require("./monad/state/stateMonad")

import st = require("./stack/stack")

var fnc = <X>(st:st.stack.Stack):ms.monad.state.State<X,X[]> =>
st.pop()
.bind(e => st.pop())
.bind(e => st.push(20))
.bind(e => st.pop())
.bind(e => st.push(e*5))

console.log(fnc(new st.stack.Stack<number>()).execState([1,2,3])) //=> [100,3]


外部モジュールのstateMonad.tsstack.tsimportが必要。

ここでも相対パスを指定する。


コンパイル

コンパイルする際は、--module commonjsのオプションを付加する。

Webで見ると--module amdでも良いと書いてあるが、私の環境では実行時にエラーとなった。

rootに移動し、コンパイルコマンドを発行する。


/root

ts stateTest.ts --module commonjs



実行

rootに移動し、node.jsにて実行する。


/root

node stateTest.js // [100,3]


期待した値が表示された。


まとめ

以前importに指定していたmoduleがdeprecatedになっているため、requireを使用する。

requireには相対パスを指定する(別の方法があるかもしれません)。

外部クラスを使用する場合は、importに使用した変数(今回の場合はms)と、フォルダ階層を.で区切り指定する。

コンパイル時には、--module commonjsのオプションを付加する。