5

I am trying to typehint a bunch of javascript in Google Script, and I have gotten as far as trying this:

/**
 *  Get (named) range given by name
 *
 *  @param {String} name 
 *  @return {Range}
 *
 */
function getRange(name) {
  return SpreadsheetApp.getActiveSpreadsheet().getRangeByName(name);
}

Which displays well and gives the same typehint as the builtin getRangeByName, however it does not actually work, i.e. the auto-complete script editor does not autocomplete when I type something like getRange("hello").get", like it should. Should I be name spacing the Range or am I doing something else wrong?

Cryvate
  • 321
  • 3
  • 13
  • 2
    Use [tag:clasp] with local [tag:ide] – TheMaster Oct 27 '20 at 12:41
  • I'm not sure if I understood, do you mean the Cntrl + Space autocomplete feature? – Jescanellas Oct 27 '20 at 14:15
  • Off-note: is your `name` parameter really an instance of a `String` and not a string literal? When annotating with JSDoc, please, pay attention to what each type means, `string` and `String` do not mean the same thing. – Oleg Valter is with Ukraine Oct 27 '20 at 18:10
  • also: you will need [this](https://www.npmjs.com/package/@types/google-apps-script) and yes, as TheMaster said, a local IDE and CLASP. You can't make the script editor magically know what the `Range` type is – Oleg Valter is with Ukraine Oct 27 '20 at 18:12
  • @OlegValter thanks on the string note. I am a Python programmer by day, this is a side project. CLASP does seem the way forward, however surely there must be some way I can tell it what the `Range` is, because Google itself manages it? Surely if I matched what they write in their JSDoc for e.g. `SpreadsheetApp` methods, I could get the same behaviour? – Cryvate Oct 27 '20 at 19:19
  • 1
    @Cryvate - good luck doing that :) Even if you did manage to reproduce it somehow, I don't think it is worth the time and effort as Google could change that at any time. Better use an IDE such as VS Code and install a `@types/google-apps-script` npm package - your life will never be the same again. That said, Google plans to migrate to a new online editor that uses the same engine (Monaco), so when they release it, any effort poured into trying to work around current limitations will go to waste. – Oleg Valter is with Ukraine Oct 28 '20 at 00:10

2 Answers2

4

The current Google Apps Script IDE doesn't use local JSDOC to extend the autocomplete feature. Options:

  1. Create a Goole Apps Script library and attach it to your project
  2. Use another IDE

Regarding using another IDE at this time there is a tool called CLASP that helps to download/upload script which make it possible to use other IDEs.

Resources

Related

Other related

Rubén
  • 34,714
  • 9
  • 70
  • 166
  • I am actually using a library as in the second link, so it is possible to get suggestions, but just not for types like `Range`? – Cryvate Oct 27 '20 at 20:14
  • @Cryvate I'm sorry, I don't understand what you mean. Please bear in mind that JSDOC support in Google Apps Script IDE is limited. – Rubén Oct 27 '20 at 20:17
  • 1
    So I have a library ScriptsLocal that I include in another script, and I can type hint a function in ScriptsLocal e.g. getRange(name) with name type `string` and its return type `Sheet`, and this will show up in the other script when I type ScriptsLocal.getRange. So the JSDOC is being picked up, but either my reference to `Sheet` is wrong (I tried things like `SpreadsheetApp.Sheet`) or I am doing something else wrong (using JSDOC wrong, as I said, I am not a JS programmer by trade). – Cryvate Oct 27 '20 at 20:47
  • Thanks. I have now done so: https://stackoverflow.com/questions/64573838/how-to-type-hint-google-types-in-google-scripts-library – Cryvate Oct 28 '20 at 13:27
1

One can add type hints for a plain old javascript object by defining a class for it, and adding a comment above the constructor defining the parameter types

onEdit(e) (when a cell is edited) has an event, e as an input. Unfortunately, it there is no Event type in the script editor. We can fix that by defining an event class and adding a type hint for the parameter e like so:

class User {
   /**
    * @param {string} email
    * @param {string} nickname
    */
    constructor(email, nickname) {
    this.email = email;
    this.nickname = nickname;
  }
}

class Range {
   /**
    * @param {Number} columnEnd
    * @param {Number} columnStart
    * @param {Number} rowEnd
    * @param {Number} rowStart
    */
    constructor(columnEnd, columnStart, rowEnd, rowStart) {
    this.columnEnd = columnEnd;
    this.columnStart = columnStart;
    this.rowEnd = rowEnd;
    this.rowStart = rowStart;
  }
}

class Event {
   /**
    * @param {string} value
    * @param {User} user
    * @param {ScriptApp.AuthMode} authMode
    * @param {Range} range
    * @param {string} oldValue
    */
    constructor(value, user, authMode, range) {
    this.value = value;
    this.user = user;
    this.authMode = authMode;
    this.range = range;
  }
}

/**
* @param {Event} e
*/
function onEdit(e) {
  // now we have autocompletion on e properties
  SpreadsheetApp.getUi().alert(JSON.stringify(e));
  SpreadsheetApp.getUi().alert(e.user.email);
}
spacether
  • 2,136
  • 1
  • 21
  • 28