TypeScript restrictions in Office Scripts

Office Scripts use the TypeScript language. For the most part, any TypeScript or JavaScript code will work in Office Scripts. However, there are a few restrictions enforced by the Code Editor to ensure your script works consistently and as intended with your Excel workbook.

No 'any' type in Office Scripts

Writing types is optional in TypeScript, because the types can be inferred. However, Office Scripts requires that a variable can't be of type any. Both explicit and implicit any are not allowed in Office Scripts. These cases are reported as errors.

Explicit any

You cannot explicitly declare a variable to be of type any in Office Scripts (that is, let value: any;). The any type causes issues when processed by Excel. For example, a Range needs to know that a value is a string, number, or boolean. You will receive a compile-time error (an error prior to running the script) if any variable is explicitly defined as the any type in the script.

The explicit `any` message in the Code Editor's hover text.

The explicit `any` error in the console window.

In the previous screenshot, [2, 14] Explicit Any is not allowed indicates that line #2, column #14 defines any type. This helps you locate the error.

To get around this issue, always define the type of the variable. If you are uncertain about the type of a variable, you can use a union type. This can be useful for variables that hold Range values, which can be of type string, number, or boolean (the type for Range values is a union of those: string | number | boolean).

Implicit any

TypeScript variable types can be implicitly defined. If the TypeScript compiler is unable to determine the type of a variable (either because type is not defined explicitly or type inference isn't possible), then it's an implicit any and you will receive a compilation-time error.

The implicit `any` message in the Code Editor's hover text.

The most common case on any implicit any is in a variable declaration, such as let value;. There are two ways to avoid this:

  • Assign the variable to an implicitly identifiable type (let value = 5; or let value = workbook.getWorksheet();).
  • Explicitly type the variable (let value: number;)

No inheriting Office Script classes or interfaces

Classes and interfaces that are created in your Office Script cannot extend or implement Office Scripts classes or interfaces. In other words, nothing in the ExcelScript namespace can have subclasses or subinterfaces.

Incompatible TypeScript functions

Office Scripts APIs cannot be used in the following:

eval is not supported

The JavaScript eval function is not supported for security reasons.

Restricted identifiers

The following words can't be used as identifiers in a script. They are reserved terms.

  • Excel
  • ExcelScript
  • console

Only arrow functions in array callbacks

Your scripts can only use arrow functions when providing callback arguments for Array methods. You cannot pass any sort of identifier or "traditional" function to these methods.

const myArray = [1, 2, 3, 4, 5, 6];
let filteredArray = myArray.filter((x) => {
  return x % 2 === 0;
});
/*
  The following code generates a compiler error in the Office Scripts Code Editor.
  filteredArray = myArray.filter(function (x) {
    return x % 2 === 0;
  });
*/

Unions of ExcelScript types and user-defined types aren't supported

Office Scripts are converted at runtime from synchronous to asynchronous code blocks. The communication with the workbook through promises is hidden from the script creator. This conversion doesn't support union types that include ExcelScript types and user-defined types. In that case, the Promise is returned to the script, but the Office Script compiler doesn't expect it and the script creator can't interact with the Promise.

The following code sample shows an unsupported union between ExcelScript.Table and a custom MyTable interface.

function main(workbook: ExcelScript.Workbook) {
  const selectedSheet = workbook.getActiveWorksheet();

  // This union is not supported.
  const tableOrMyTable: ExcelScript.Table | MyTable = selectedSheet.getTables()[0];

  // `getName` returns a promise that can't be resolved by the script.
  const name = tableOrMyTable.getName();

  // This logs "{}" instead of the table name.
  console.log(name);
}

interface MyTable {
  getName(): string
}

Constructors don't support Office Scripts APIs and console statements

console statements and many Office Scripts APIs require synchronization with the Excel workbook. These synchronizations use await statements in compiled runtime version of the script. await is not supported in constructors. If you need classes with constructors, avoid using Office Scripts APIs or console statements in those code blocks.

The following code sample demonstrates this scenario. It generates an error that says failed to load [code] [library].

function main(workbook: ExcelScript.Workbook) {
  class MyClass {
    constructor() {
      // Console statements and Office Scripts APIs aren't supported in constructors.
      console.log("This won't print.");
    }
  }

  let test = new MyClass();
}

Performance warnings

The Code Editor's linter gives warnings if the script might have performance issues. The cases and how to work around them are documented in Improve the performance of your Office Scripts.

External API calls

See External API call support in Office Scripts for more information.

See also