enuchi / React-Google-Apps-Script

This is your boilerplate project for developing React apps inside Google Sheets, Docs, Forms and Slides projects. It's perfect for personal projects and for publishing complex add-ons in the Google Workspace Marketplace.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typescript support for custom functions

sheldoncoates opened this issue · comments

Is there any way to support typescript in custom functions?

This is my current webpack config:

// webpack settings for copying files to the destination folder
const copyFilesConfig = {
    name: 'COPY FILES - appsscript.json',
    mode: 'production', // unnecessary for this config, but removes console warning
    entry: copyAppscriptEntry,
    output: {
        path: destination,
        publicPath,
    },
    optimization: {
        minimize: false,
    },
    plugins: [
        new CopyWebpackPlugin({
            patterns: [
                {
                    from: copyAppscriptEntry,
                    to: destination,
                },
                {
                    from: './src/server/function.js', // custom function js file
                    to: destination,
                },
            ],
        }),
    ],
}

All it does it take the js file and copies it into dist. I've attempted to convert js to ts with ts-loader but webpack adds a bunch of bootstrap and EEFI to the function file it outputs which google server doesn't like.

Just wondering if anyone has overcome this and is able to share how? Thanks!

You should review the webpack config here in this repo. Check out the server section specifically.

Do you need to include the custom function inside src/server/index.ts? When I do the custom function isn't recognized by google sheets. This is why I have the custom function file as a straight copy over - the existing webpack hasn't ever worked for me for some reason.

Yes and it needs to be exported from src/server/index.ts in the format shown.

Doesnt seem like google sheets recognizes it as a custom function

./src/server/custom-function.js:

 * Multiplies an input value by 2.
 * @param {number} input The number to double.
 * @return The input multiplied by 2.
 * @customfunction
 */
export function DOUBLE(input) {
    return input * 2
}

./src/server/index.ts:

import * as CustomFunction from './custom-function'
const { DOUBLE } = CustomFunction

export {DOUBLE}

dist/code.js snippet

    }, (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        /**
 * Multiplies an input value by 2.
 * @param {number} input The number to double.
 * @return The input multiplied by 2.
 * @customfunction
 */
        function DOUBLE(input) {
            return 2 * input;
        }
        __webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, {
            DOUBLE: () => DOUBLE
        });
    } ], __webpack_module_cache__ = {};

Any idea?

At the top of code.gs where all the global definitions are I see that the custom function doesn't have the JSDOC

var global = this;

function DOUBLE() {}

could this be why?

This seemed to work for me -- give below a try:

// src/server/index.ts

declare global {
  var global;
}

import { DOUBLE } from './custom-function';

export { DOUBLE };

/**
 * Multiplies an input value by 2.
 * @param {number} input The number to double.
 * @return The input multiplied by 2.
 * @customfunction
 */
global.DOUBLE = DOUBLE;

Were you able to get this to work @sheldoncoates ?

No, no matter what i did the functions werent globally exported. Had to move on to something else so i think ill have to circle back to this when i can take another look at converting to ts

@enuchi i ended getting this working now, its unfortunate that you have to specify the custom function jsdoc like that in the src/server/index.ts but what can you do 🤷 thanks for the help!

@enuchi just realized that when the file uses Google Sheet specific class/function and the file is a typescript file, it doesn't seem to recognize the uses; Cannot find name 'PropertiesService'. for example. Does this work you if you use a sheets specific class inside a ts file?

Are you using the boilerplate from this repo?

yes, the project is based off this boilerplate. am i missing something obvious for how ts can tell what SpreadsheetApp is when building the project?

All the types are defined in the gas-types-detailed package, which should be referenced in your tsconfig.json file: https://github.com/enuchi/React-Google-Apps-Script/blob/main/tsconfig.json#L3