GASの新エディタで自動補完を効かせて快適にプログラムを組もう

GASの新エディタで自動補完を効かせて快適にプログラムを組もう

GASの新しいエディタが、一部アカウントに配信されてきているようです。

今回は、新しいエディタで「型の補完」が、どの程度効くようになっているか確かめてみました。

要約

ざっと、新エディタを触ってみた今のところ(2020/12/15時点)の感想です。

  • 変数の型が推論される(型補完の精度は、型アノテーションができないTypeScriptと同等?)
  • functionの引数・返り値についてはJSDocを書けば型の指定ができる(JSDocを書かなければ型は付かない)
  • functionのJSDocでは型変数(ジェネリクス)も使える

変数の型が推論される

新エディタでは、「型の推論」が効きます。

「型の推論」というのは、プログラムを自動解析して、変数にどの型の値が入っているかを推測してくれる機能です。

以下、いくつか具体例を見てみましょう。

初期化した「値」によって、変数の型を推論する

たとえば、変数「n」にnumber型の値「1」を代入すると、以降、変数「n」はnumber型として推論されます。

その結果、次のように「n.」と入力すると、number型のメソッドが候補表示されます

同じように、変数「s」にstring型の値「あいうえお」を入れた後に、「s.」と入力すると、string型のメソッドが候補表示されます

当然、boolean型、Date型にも対応しています。

typeof演算子、instanceof演算子で、変数の型を絞り込む

スプレッドシートから「Range」オブジェクトの「getValue」メソッドで値を取得した場合、型は1つには確定しません。

というのは、セルには、「string」「number」「boolean」「Date」など、様々な型の値が入っている可能性があるからです。

このときに、typeof演算子やinstanceof演算子で型を判定することで、型を絞り込んで、自動補完に反映させることができます。

function test_narrowing() {
  const value = SpreadsheetApp.getActiveSheet().getRange(1,1).getValue();
  //valueはObjectとして推論(=どの型か決まらない状態)

  if (typeof value === 'number') {
    //valueはnumber型として推論
    
  } else if (typeof value == 'string') {
    //valueはstring型として推論
    
  } else if (typeof value == 'boolean') {
    //valueはboolean型として推論

  } else if (value instanceof Date ) {
    //valueはDate型として推論  

  }
}

それぞれの場所で「value.」と入力すると、推論された型に応じて、候補表示が変わることがわかります。

配列の型を絞り込む

「getValues」メソッドのように、返り値が配列になる場合は、少し複雑です。

先ほどと同じように、単に「getValues[y][0]」の型を判定するだけでは、型の補完は効きません。

型の補完を効かせる方法は、いくつかあります。

たとえば、次のように、使いたい値をいったん変数に格納すれば、型を絞り込むことができます。

functionの引数・返り値については、JSDocを書けば型の指定ができる

functionについては、単にfunctionを書くだけでは、引数・返り値の型は推論されません。

次の画像では、2つの数を足すfunction「sum_ng」を呼び出して、計算結果を変数「s」に格納しています。

変数「s」は、今回のプログラムの流れだとnumber型になるのですが、「s.」と入れても、入力候補が表示されません。

JSDocで返り値の型を推論する

functionに対して引数・返り値の型を推論させるためには、JSDocを書きましょう。

JSDocというのは「一定の書式に従ってfunctionの処理内容、引数、返り値の内容について書くコメント」で、functionの前に記述します。

たとえば、次のソースコードの1行目~6行目がJSDocです。

/**
 * 2つの値の合計を取ります
 * @param {number} a - 1つめの引数
 * @param {number} b - 2つめの引数
 * @return {number} - 合計
 */
function sum(a, b) {
  return a + b;
}

このように、適切にJSDocを書けば、返り値の型が推論されます

JSDocで引数の型チェックを行う

また、JSDocに応じて、引数の型チェックも行うこともできます

たとえば、先ほどのsum関数は、JSDocで、引数「a」「b」の両方にnumber型の値を入力することを指定しています。

そのため、それ以外の型の値を指定すると、次のように、赤波下線で警告が表示されます

functionのJSDocでは型変数(ジェネリクス)も使える

functionのJSDocを書くときには、型変数も使えるようです。

たとえば、次のような、2つの引数を要素とする配列を返すfunction「createArray」を定義してみましょう。

/**
 * 2つの引数を要素とする配列を返す。
 * @template T
 * @param {T} a - 1つめの引数
 * @param {T} b - 2つめの引数
 * @return {T[]} - 合計
 */
function createArray(a, b) {
  return [a, b];
}

このfunctionの返り値の型は、引数の型に応じて変わります。

  • 引数「a」「b」にnumber型の値を指定すれば、返り値はnumber型の配列(=number[]型)
  • 引数「a」「b」にstring型の値を指定すれば、返り値はstring型の配列(=string[]型)
  • 引数「a」「b」にDate型の値を指定すれば、返り値はDate型の配列(=Date[]型)

このような指定をするときに、型変数(ジェネリクス)を使います。

先ほどのプログラム(JSDoc)では、3行目の「@template T」で型変数を定義して、引数、返り値を、この型変数「T」を使って表現しています。

このようなJSDocを準備しておくと、返り値の型が適切に推測されます。

返り値の型が推論される例

下記の例では、引数に「number型の値」を指定しているので、返り値は「number型の配列」になります。

その結果、変数「numArr」は「number型の配列」だと推論されます。

その結果、「numArr[0]」はnumber型と推論され、number型のメソッドが候補表示されます。

一方で、引数に「Date型の値」を指定すると、返り値は「Date型の配列」になります。

同じようにして、「dateArr[0]」はDate型と推論され、Date型のメソッドが候補表示されます。

まとめ

今までは、ローカル環境にClasp環境をインストールしてTypeScriptを使わないと、このような型推論が効きませんでした。

今後は、Google Apps Scriptの新しいエディタを使うことで、(Clasp環境と同等とまでは行きませんが)かなり快適にプログラムが組めそうです。