Google Apps ScriptのgetValueの型をいい感じにする

GASでスプレッドシートから値を読むときに getValue とか getValues とか使うけど、 @types/google-apps-script の定義だと戻り値の型が any になっていて扱いにくい。

公式のドキュメントには戻り値の型について

The value may be of type Number, Boolean, Date, or String depending on the value of the cell.

と書いてあるので、型がこの4つのどれかになってるかどうか判定する関数を用意するといい感じになる。

type TypeMap = {
  string: string;
  number: number;
  boolean: boolean;
  Date: Date;
};

type ValueType = TypeMap[keyof TypeMap];

function checkType<T extends keyof TypeMap>(x: ValueType, typeName: T): x is TypeMap[T] {
  if (typeName === 'Date') {
    return x && typeof x === 'object' && x.constructor.name === 'Date';
  } else {
    return typeof x === typeName;
  }
}

function assertType<T extends keyof TypeMap>(x: ValueType, typeName: T, message?: string): asserts x is TypeMap[T] {
  if (!checkType(x, typeName)) {
    throw new Error(message);
  }
}

checkType の定義に使ってる機能はUser-Defined Type Guards、 assertType の定義に使ってるのはAssertion Functionsというらしい。