Google Apps ScriptをTypeScriptで書いてみた

2021.10.21

はじめに

アノテーションの髙嶋です。

Google Apps Script(以降、GAS)を書く際、みなさんはどうやってコードを書いてますか?私はTypeScriptで書いています。
今回はGASをTypeScriptで記述して実行する手順を書いています。

なぜTypeScriptで書くのか

型があるって素敵じゃないですか?

JavaScriptだと変数の宣言時や関数のパラメータや戻り値に対して型は指定せず、実行時に入っている値をもとに決定されます。(動的型付け言語)
言ってしまえば「なんでも入れられます」という状態です。なので、変数に対して誤った値を設定していても気づけず、実行しないと問題なく動作するか確認できません。

一方、TypeScriptは変数の宣言時やメソッドのパラメータや戻り値にstringやnumberなどの型を指定することができます。(静的型付け言語)
型を指定することで、どのような値を設定すればいいか、メソッドから戻ってくるのかがわかり、誤った値を設定をしてしまうのを防ぎやすくなります。

※Visual Studio Codeでは、設定している変数の型が誤っているとエラーを表示してくれます

ソースコードの記述量はJavaScriptよりは増えてしまうかもしれませんが、個人的にはTypeScriptの方が開発しやすいと思っています。

実行環境

前回の記事で書いている環境が構築されていることが前提となります。
今回の記事はアプリケーションの新規作成まで実施した状態から開始しています。

claspを使ってGoogle Apps Scriptの開発環境を構築してみた

使用しているエディターはVisual Studio Codeです。

実施手順

どうやればGASの開発をTypeScriptで行えるようになるか。
ひとことで言ってしまうと、TypeScriptでコードを書いてpushすればclaspがいい感じにしてくれます。

パッケージインストール

TypeScript用のnpmパッケージをインストールして、初期化を実行します。

npm install typescript
npx tsc --init

TypeScriptの設定ファイルである"tsconfig.json"が作成されます。今回はデフォルト設定のまま使用しています。

ソースファイル作成

実際に下記のようなコードを書いて試してみます。

main.ts

import { Hoge } from "./hoge";
import { Huga } from "./huga";

export function handler() {
    let hoge = new Hoge();
    hoge.message('test1')

    let huga = new Huga('test2');
    huga.message()
    huga.message()
}

このファイルから処理を実行し、他クラスのインスタンスを生成してメソッドを実行します。

hoge.ts

export class Hoge {

    constructor(
    ) {
    }

    public message(
        value: string
    ) {
        console.log(`hogehoge:${value}`);
    }
}

メソッドのパラメータで受けとった値をログに出力するメソッドを作成しています。

huga.ts

export class Huga {

    private cnt: number = 0;

    constructor(
        private readonly value: string
    ) {
    }

    public message() {
        console.log(`hugahuga:${this.value} ${++this.cnt}回目`);
    }
}

コンストラクタで受けとった値をログに出力するメソッドを作成しています。 また、実行するたびにn回目とカウントアップして出力しています。

ファイル作成後の配置はこんな感じになります。

./
├ node_modules
├ .clasp.json
├ appsscript.json
├ hoge.ts
├ huga.ts
├ main.ts
├ package.json
├ package-lock.json
└ tsconfig.json

push

ソースファイルが書き終わったら、pushします。

clasp push

ファイルがpushされたので、WEBエディターで確認します。
拡張子gsのファイルが生成・配置されました。

各ファイルの中身を見ると、コードが自動で変換されていることが確認できます。
※TypeScriptで記述しても、コード変換により型の記述は削除されます

main.gs

// Compiled using dev 1.0.0 (TypeScript 4.4.4)
var exports = exports || {};
var module = module || { exports: exports };
exports.handler = void 0;
//import { Hoge } from "./hoge";
//import { Huga } from "./huga";
function handler() {
    var hoge = new Hoge();
    hoge.message('test1');
    var huga = new Huga('test2');
    huga.message();
    huga.message();
}
exports.handler = handler;

hoge.gs

// Compiled using dev 1.0.0 (TypeScript 4.4.4)
var exports = exports || {};
var module = module || { exports: exports };
exports.Hoge = void 0;
var Hoge = /** @class */ (function () {
    function Hoge() {
    }
    Hoge.prototype.message = function (value) {
        console.log("hogehoge:" + value);
    };
    return Hoge;
}());
exports.Hoge = Hoge;

huga.gs

// Compiled using dev 1.0.0 (TypeScript 4.4.4)
var exports = exports || {};
var module = module || { exports: exports };
exports.Huga = void 0;
var Huga = /** @class */ (function () {
    function Huga(value) {
        this.value = value;
        this.cnt = 0;
    }
    Huga.prototype.message = function () {
        console.log("hugahuga:" + this.value + " " + ++this.cnt + "\u56DE\u76EE");
    };
    return Huga;
}());
exports.Huga = Huga;

動作確認

main.gsを選択して関数を実行すると、ログが出力され動作することが確認できます。

あとは、実際にコードをガリガリ書いて、pushして、動作確認してを繰り返しながら開発を進めていくようになります。
今回は触れていませんが、インターフェースや継承なども記述することはできます。

最後に

プログラムは書いて動作確認して終わり!ではなく、継続して機能追加などメンテナンスしていくものだと思っています。
そのためには少しでも読みやすい、変更しやすいコードを書くことが大切になります。
型がなくてもきれいなコードを書ける人もいると思いますが、型があることでさらにきれいなコードが書けるようになると考えています。

最後までお読みいただきありがとうございました。 それでは、また次の記事でお会いしましょう。

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。