Use Typescript with Google Apps Script
Now it's possible to use Typescript to develop Google Apps Script projects but this could not be done directly on the Apps Script Editor.
According to Develop Apps Script using TypeScript the easier way is by using clasp.
Related
- Enabling autocomplete for Google Apps Script in locally-installed IDE
I've been looking into a similar scenario this past couple of weeks (not using TypeScript but still ES6/ES7).
Some of the things I've found that you might find helpful for what you're trying to achieve:
- GAS webpack plugin allows you to use webpack for module loading within GAS by detecting when you're assigning to the global object and then generating a top level function which GAS can run. This means your import and exports will all be handled by webpack so you don't have to remove them.
- I wasn't able to get
import * as x from y
syntax to work howeverimport { x } from y
andimport x from y
worked fine when using webpack. - You can include your HTML as a string in your bundle using HTML loader.
If you don't want to use webpack, one solution is to put all your code in a single app.ts
file, create an object containing all of your functions, set the functions to be top-level so they can be picked up by GAS. You could also export the container object and use it in a test suite. When you compile with Babel use the babel-plugin-transform-remove-export plugin to remove the export statement.
const app = {
onInstall: () => { ...
},
onOpen: () => { ...
}
}
const { onOpen, onInstall } = app;
export { app };
Background
Things have changed since you wrote this question and there is a better support for TypeScript for AppsScript development nowadays. Like Aliabbas Merchant said, the best way to compile TS to GAS is using clasp, which is a CLI tool for developing AppsScript apps. Clasp uses ts2gas library under the hood to convert TS to GAS, so there is no more need for Webpack or any other bundler just for converting the code into AppsScript.
What Aliabbas Merchant didn't mention is that ts2gas doesn't (yet!) support export
syntax, which causes linter errors when developing, and won't be accepted nicely by the IDE (even if disabling the linter, the IDE will not recognize the imported vars and won't consider them as a reference to the exports...)
The Problem
The problem starts from the fact that AppsScript doesn't use modules system and every top-level var that is defined is also accessible from other files (in contrast to TS that "wrapps" files as modules). The problem with the current version of ts2gas is that it transpiles the following statement:
export var x = 5;
into:
exports.x = 5
So, after clasp converts .ts
to .gs
, when another file of .gs
tries to access the exported var, it doesn't find it. Actually, this var isn't stored as a global var like expected, but inside the exports
object (which is itself a global var). If we could "cheat" the compiler somehow, so it both keeps the var in the global env, even though it is also exported (so we can work with TS with no errors), we would win.
Solutions
So we're looking for a workaround. You can find some in clasp's using TS docs (https://github.com/google/clasp/blob/master/docs/typescript.md), but there is another trick that I've found the most simple:
Defining the var locally (without exporting it), and later on exporting an object with all the vars (which could be also functions, of course) we want to export. TS will behave as exporting the vars regularly (it's a syntactic sugar for exporting vars), but the compiler will keep the vars both global and inside an exports object.
Example
const a = 5;
function b() {
return 'Hello World';
}
export {
a,
b
}
This way, the vars are truly exported and can be used in TS as usual, but would also stay at the global env after compiling to GAS files (the compiler would actually add them to the export
object, but we shouldn't care about it).