これはWindows Scripting Host向けTypeScriptコンパイラです。
npm install tsc4wshts
declare const fso: Scripting.FileSystemObject;
for (const e = new Enumerator(WScript.Arguments.Unnamed); !e.atEnd(); e.moveNext()) {
const arg = e.item();
const file = fso.GetFile(arg);
const d = new Date(file.DateLastModified);
WScript.Echo(${file.Path} ${file.Size} ${d.toLocaleString()});
}
`
main.tsというファイルを用意したとしてexample.wsfという名前のスクリプトに変換する場合には以下のコマンドを実行します。
> npx tsc4wsh main.ts -o example.wsf
$3
private-modules以下に私がスクリプト作成に利用している、ライブラリ・型定義を置いています。
ライブラリ
- debug-context
- filesystemobject-util
- iterables
- registry
- wscript-util
- wshtest
- xmlwriter
型定義
- dom3
- useragent
- windows-installer
- wsh
- xmlstream
- virtualbox(未完成)
$3
VS Codeなどのエディターにはコンパイルエラーを指摘してくれる機能がありますが、適切なtsconfig.jsonファイルを用意していないとprivate-modules以下のライブラリを参照している場合、エラーになってしまいます。
そこでtsconfig.jsonを出力するオプションを用意しています。以下のコマンドを実行してください。
> npx tsc4wsh --init
すると以下のようなtsconfig.jsonが出力されます。
`json
{
"compilerOptions": {
"target": "es3",
"module": "none",
"outFile": "./dummy.js",
"downlevelIteration": true,
"strict": true,
"strictNullChecks": true,
"types": [
"windows-script-host",
"activex-scripting",
"activex-adodb"
],
"lib": [
"ESNext"
],
"typeRoots": [
"node_modules/tsc4wsh/private-modules",
"node_modules/tsc4wsh/private-modules/@types"
]
}
}
`
typeRootsにprivate-modulesのパスが指定されますので、エディター上でもコンパイルが通るようになります。
tsc4wshがやること
tsc4wshで行っていることは以下のとおりです。
- private-modules以下をtypeRootsに追加
- TypeScriptのトランスパイル
- WSF形式での出力
- polyfillの追加
- WshRuntimeテンプレートリテラル対応
- VBScriptテンプレートリテラル対応
- declare constで宣言された変数
- 配列リテラルの最後のカンマ
- default、forなどの予約語の名前のプロパティアクセス
- JScriptで未サポートな正規表現のチェック
- テンプレートリテラル内の非ASCII文字のエスケープ
- @onendが付けられた関数
$3
private-modules以下にWSHスクリプトで使われそうなライブラリや型定義を用意しています。
自分でスクリプトを書くために必要な部分だけを宣言、定義しているため、不十分なところがままありますが、必要なときは修正してください。そしてPull Requestをお願いします。
$3
当然のことながらTypeScriptをトランスパイルしています。ES3で出力しています。
$3
JSファイルで出力しているとソース内で使用している文字コードがSHIFT-JISと見なされてしまいます。
UTF-8で扱ってもらった方がトランスパイル後の出力的にも楽なのでWSF形式で出力し、XMLの文字コード指定でUTF-8を指定しています。
$3
そのままではJScriptでサポートされていないメソッドの呼び出しなどでエラーになってしまいますので、使用しているメソッドを優先的にたりないものを追加したり、ES2015以降の仕様と異なっているものを差し替えています。
Symbolも若干無理やり気味ですがサポートしているので、generatorやfor-ofなども使えます。
$3
タグ付きテンプレートリテラルとしてWshRuntimeを用意しています。
このタグ付きテンプレート内に記述した内容はWSFのruntime要素内に記述されます。
runtime要素にはスクリプトのコマンドラインパラメーターの説明などを記述できます。
$3
JScriptではどうしてもできないことがVBScriptならできる、ということがたまにあります。
そのときにはタグ付きテンプレートリテラルとしてVBScriptを用意していますので、このタグ付きテンプレートリテラル内にVBScriptを記述してください。
$3
`ts
declare const fso: Scripting.FileSystemObject;
`
のような記述があると、出力するWSFファイルに
`xml
`
という行が追加されます。つまりグローバルな定数としてfsoというprogidがScripting.FileSystemObjectなオブジェクトが追加されます。
このとき指定する型はActiveXObjectNameMapというinterfaceに指定されたプロパティであることに注意してください。
Scripting.FileSystemObjectは型名とprogidが一致していますが、progidがWScript.Shellである型はIWshRuntimeLibrary.WshShellです。
progidに対応する型がわからない場合は
`ts
declare const wshShell: ActiveXObjectNameMap['WScript.Shell'];
`
のように一度書いてみて、wshShellにマウスカーソルを合わせて型情報が見るという手も使えます。
$3
ES5以降のJavaScriptでは配列リテラルの最後に,があっても無視されますが、
JScriptでは配列リテラルの最後に,があると配列の要素にundefinedが追加されてしまいます。
`ts
const arr = [
1,
2,
3,
];
// -> transpileすると
// var arr = [
// 1,
// 2,
// 3,
// ];
// と変換されるが、これは
// var arr = [1, 2, 3, undefined];
// と同じになる
`
そこでJScriptへの変換時に最後のカンマを出力しないようにしました。
`ts
const arr = [
1,
2,
3,
];
// -> transpileすると
// var arr = [
// 1,
// 2,
// 3
// ];
// と変換される。
$3
ES5以降ではSymbol.forなどプロパティ名であれば予約語も使えるようになりましたが、JScriptではプロパティ名でも予約語を使うとエラーになります。
そこでSymbol.forのようなプロパティアクセスはSymbol['for']のようにインデックスでのアクセスに置き換えます。
$3
JScriptでは後読みや名前付きキャプチャをサポートしていません。
またg、i、m以外のフラグも未サポートです。
そこでこれらを使用していたらエラーになるようにしています。
$3
テンプレートリテラル内に日本語文字のような非ASCII文字を記述していると、トランスパイル後には'\u3042\u3044\u3046'のようにエスケープされた状態になっています。
これはTypeScriptの標準的な動作なのですが、生成されたスクリプトが読みづらくなるのでエスケープしないように修正しています。
$3
以下のようにトップレベルに記述した関数のコメントに@onendをつけると、プログラムの最後で自動的に呼び出されるようにしています。
`ts
// @onend
function onendfunction() {
// ...
}
``