or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

@babel/plugin-proposal-record-and-tuple

@babel/plugin-proposal-record-and-tuple is a Babel plugin that transforms the proposed Record and Tuple syntax into JavaScript code that can run in current environments. Records and Tuples are immutable data structures proposed for JavaScript that provide value equality semantics and deep immutability guarantees. The plugin enables developers to use the new syntax #{...} for records and #[...] for tuples in their code, transforming them into polyfill implementations that maintain the expected behavior.

Package Information

  • Package Name: @babel/plugin-proposal-record-and-tuple
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-proposal-record-and-tuple

Core Imports

// ES modules
import recordTuplePlugin from "@babel/plugin-proposal-record-and-tuple";

// CommonJS
const recordTuplePlugin = require("@babel/plugin-proposal-record-and-tuple");

// For type definitions (TypeScript)
import type { Options } from "@babel/plugin-proposal-record-and-tuple";
import type { types as t, NodePath } from "@babel/core";
import type { declare } from "@babel/helper-plugin-utils";

Basic Usage

// Babel configuration (.babelrc.js or babel.config.js)
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-record-and-tuple", {
      syntaxType: "hash",
      importPolyfill: true
    }]
  ]
};

// Input code with Record and Tuple syntax
const record = #{
  name: "Alice",
  age: 30,
  hobbies: #["reading", "gaming"]
};

const tuple = #[1, 2, 3, #{x: 4, y: 5}];

// Transformed output (when importPolyfill: true)
import { Record as _Record, Tuple as _Tuple } from "@bloomberg/record-tuple-polyfill";

const record = _Record({
  name: "Alice", 
  age: 30,
  hobbies: _Tuple("reading", "gaming")
});

const tuple = _Tuple(1, 2, 3, _Record({x: 4, y: 5}));

Capabilities

Plugin Function

The main export is a Babel plugin function that transforms Record and Tuple syntax.

import { declare } from "@babel/helper-plugin-utils";
import syntaxRecordAndTuple from "@babel/plugin-syntax-record-and-tuple";
import type { Options as SyntaxOptions } from "@babel/plugin-syntax-record-and-tuple";
import { types as t, type NodePath } from "@babel/core";

/**
 * Babel plugin factory function for transforming Record and Tuple syntax
 * @param api - Babel API object with version assertion
 * @param options - Plugin configuration options
 * @returns Babel plugin object with visitor methods
 */
const recordTuplePlugin = declare<State>((api, options: Options) => {
  api.assertVersion(7);
  return {
    name: "proposal-record-and-tuple",
    inherits: syntaxRecordAndTuple,
    visitor: {
      Program(path: NodePath<t.Program>, state: State): void;
      RecordExpression(path: NodePath<t.RecordExpression>, state: State): void;
      TupleExpression(path: NodePath<t.TupleExpression>, state: State): void;
    }
  };
});

export default recordTuplePlugin;

Plugin Options

Configuration options for customizing the plugin behavior.

import type { Options as SyntaxOptions } from "@babel/plugin-syntax-record-and-tuple";

interface SyntaxOptions {
  /**
   * Which syntax variant to use for Record and Tuple literals
   * "hash" uses #{} and #[] syntax
   * "bar" uses {||} and [||] syntax (deprecated in Babel 8)
   */
  syntaxType: "hash" | "bar";
}

interface Options extends SyntaxOptions {
  /**
   * Name of the polyfill module to import Record/Tuple from
   * @default "@bloomberg/record-tuple-polyfill"
   */
  polyfillModuleName?: string;

  /**
   * Whether to automatically import polyfill functions
   * @default !!options.polyfillModuleName
   */
  importPolyfill?: boolean;
}

export type { Options, SyntaxOptions };

Transformation Behavior

Record Expression Transformation

Transforms record literals into Record() constructor calls.

Input:

const person = #{
  name: "John",
  age: 25,
  address: #{
    street: "123 Main St",
    city: "Boston"
  }
};

Output (without polyfill import):

const person = Record({
  name: "John",
  age: 25, 
  address: Record({
    street: "123 Main St",
    city: "Boston"
  })
});

Output (with polyfill import):

import { Record as _Record } from "@bloomberg/record-tuple-polyfill";

const person = _Record({
  name: "John",
  age: 25,
  address: _Record({
    street: "123 Main St", 
    city: "Boston"
  })
});

Tuple Expression Transformation

Transforms tuple literals into Tuple() constructor calls.

Input:

const coordinates = #[10, 20];
const nested = #[1, #[2, 3], 4];
const empty = #[];

Output (without polyfill import):

const coordinates = Tuple(10, 20);
const nested = Tuple(1, Tuple(2, 3), 4);
const empty = Tuple();

Output (with polyfill import):

import { Tuple as _Tuple } from "@bloomberg/record-tuple-polyfill";

const coordinates = _Tuple(10, 20);
const nested = _Tuple(1, _Tuple(2, 3), 4);
const empty = _Tuple();

Syntax Type Options

The plugin supports two syntax variants (though "bar" is deprecated):

Hash Syntax (Recommended)

// Records use #{}
const record = #{a: 1, b: 2};

// Tuples use #[]
const tuple = #[1, 2, 3];

Bar Syntax (Deprecated in Babel 8)

// Records use {||}
const record = {| a: 1, b: 2 |};

// Tuples use [||]
const tuple = [| 1, 2, 3 |];

Polyfill Integration

When importPolyfill is enabled, the plugin automatically:

  1. Imports polyfill functions from the specified module
  2. Caches imports to avoid duplicates within the same program
  3. Handles module types (ES modules vs CommonJS)
  4. Uses unique binding names to avoid naming conflicts

Module Import Caching:

  • Uses program-scoped caching to ensure single imports per file
  • Generates unique binding names when conflicts exist
  • Supports both import statements (ES modules) and require calls (CommonJS)

Types

import { types as t, type NodePath } from "@babel/core";

/**
 * Internal state object passed between visitor methods
 */
type State = {
  programPath: NodePath<t.Program>;
};

/**
 * Cache for storing import binding names by cache key
 * Format: "Record:true" or "Tuple:false" (name:isModule)
 */
type Cache = Map<string, string>;

/**
 * WeakMap for caching imports per program AST node
 * Ensures single imports per file and avoids duplicates
 */
type ImportCache = WeakMap<t.Program, Cache>;

Configuration Examples

Basic Configuration

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-record-and-tuple", {
      syntaxType: "hash"
    }]
  ]
};

With Custom Polyfill

// babel.config.js  
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-record-and-tuple", {
      syntaxType: "hash",
      polyfillModuleName: "my-custom-polyfill",
      importPolyfill: true
    }]
  ]
};

Without Polyfill Import

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-record-and-tuple", {
      syntaxType: "hash",
      importPolyfill: false
    }]
  ]
};

Error Handling

The plugin includes validation and error handling for various scenarios:

Babel 8 Breaking Changes

In Babel 8, the syntaxType option is no longer supported and will throw an error:

// This will throw an error in Babel 8
{
  plugins: [
    ["@babel/plugin-proposal-record-and-tuple", {
      syntaxType: "hash" // ❌ Error in Babel 8
    }]
  ]
}

// Correct usage in Babel 8
{
  plugins: [
    "@babel/plugin-proposal-record-and-tuple" // ✅ No options needed
  ]
}

Option Validation

The plugin validates all options using @babel/helper-validator-option:

  • polyfillModuleName must be a string if provided
  • importPolyfill must be a boolean if provided
  • syntaxType must be either "hash" or "bar" if provided

Internal Error Handling

// Internal error when Program node cannot be found
if (!programPath) {
  throw new Error("Internal error: unable to find the Program node.");
}

Requirements

  • Babel Core: ^7.12.0 (peer dependency)
  • Node.js: >=6.9.0
  • TypeScript: Compatible with TypeScript projects (includes type definitions)

Related Packages

  • @babel/plugin-syntax-record-and-tuple: Base syntax plugin (automatically inherited)
  • @bloomberg/record-tuple-polyfill: Default polyfill implementation for Record and Tuple
  • @babel/helper-plugin-utils: Provides the declare function for plugin creation
  • @babel/helper-module-imports: Used for automatic polyfill imports
  • @babel/helper-validator-option: Used for option validation