Skip to main content
Map types (also known as dictionaries) allow you to store key-value pairs. Most of BAML’s syntax (clients, tests, classes) is represented as maps.

Syntax

map<KeyType, ValueType>
map
A mapping from keys to values
map<string, string>        // String keys to string values
map<string, int>           // String keys to integer values
map<Category, Person>      // Enum keys to class values
map<"A" | "B", string>     // Literal string keys to values

Basic Map Declaration

Maps use a simple key-value syntax without colons:
{
  key1 value1,
  key2 {
    nestedKey1 nestedValue1,
    nestedKey2 nestedValue2
  }
}
Key Points:
  • No colons between keys and values (space-separated)
  • Values can be unquoted strings, quoted strings, booleans, numbers, or nested maps
  • Classes in BAML are represented as maps

Simple Map Example

class Person {
    name string
    age int
    isEmployed bool
}

function DescribePerson(person: Person) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        Describe the person with the following details: {{ person }}.
    "#
}

test PersonDescription {
    functions [DescribePerson]
    args { 
        person {
            name "John Doe",
            age 30,
            isEmployed true
        }
    }
}

Generated Types

from typing import Dict

# When used as map<string, string>
data: Dict[str, str] = {
    "name": "John Doe",
    "occupation": "Engineer"
}

Nested Maps

Maps can contain nested map structures:
class Company {
    name string
    location map<string, string>
    employeeCount int
}

function DescribeCompany(company: Company) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        Describe the company with the following details: {{ company }}.
    "#
}

test CompanyDescription {
    functions [DescribeCompany]
    args { 
        company {
            name "TechCorp",
            location {
                city "San Francisco",
                state "California"
            },
            employeeCount 500
        }
    }
}

Generated Types

from typing import Dict
from baml_client.types import Company

company = Company(
    name="TechCorp",
    location={
        "city": "San Francisco",
        "state": "California"
    },
    employeeCount=500
)

Enum Keys

Maps can use enums as keys:
enum Category {
    A
    B
    C
}

class CategoryData {
    scores map<Category, int>
}

function AnalyzeScores(data: CategoryData) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        Analyze these category scores: {{ data.scores }}
    "#
}

test ScoreAnalysis {
    functions [AnalyzeScores]
    args {
        data {
            scores {
                A 95,
                B 87,
                C 92
            }
        }
    }
}

Generated Types

from typing import Dict
from enum import StrEnum

class Category(StrEnum):
    A = "A"
    B = "B"
    C = "C"

scores: Dict[Category, int] = {
    Category.A: 95,
    Category.B: 87,
    Category.C: 92
}

Literal String Keys

Use literal string unions for fixed key sets:
class Config {
    settings map<"development" | "staging" | "production", string>
}

test ConfigTest {
    functions [ProcessConfig]
    args {
        config {
            settings {
                development "localhost:3000",
                staging "stage.example.com",
                production "example.com"
            }
        }
    }
}

Generated Types

from typing import Dict, Literal

Environment = Literal["development", "staging", "production"]
settings: Dict[Environment, str] = {
    "development": "localhost:3000",
    "staging": "stage.example.com",
    "production": "example.com"
}

Maps with Complex Values

class Project {
    title string
    description string
}

class Team {
    projects map<string, Project>
}

function DescribeTeam(team: Team) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        Describe this team's projects: {{ team.projects }}
    "#
}

test TeamDescription {
    functions [DescribeTeam]
    args {
        team {
            projects {
                alpha {
                    title "Project Alpha",
                    description "First initiative"
                },
                beta {
                    title "Project Beta",
                    description "Second initiative"
                }
            }
        }
    }
}

Generated Types

from typing import Dict
from baml_client.types import Project, Team

team = Team(
    projects={
        "alpha": Project(
            title="Project Alpha",
            description="First initiative"
        ),
        "beta": Project(
            title="Project Beta",
            description="Second initiative"
        )
    }
)

Maps with Multiline Strings

class Project {
    title string
    description string
}

function DescribeProject(project: Project) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        Describe the project with the following details: {{ project }}.
    "#
}

test ProjectDescription {
    functions [DescribeProject]
    args { 
        project {
            title "AI Research",
            description #"
                This project focuses on developing
                advanced AI algorithms to improve
                machine learning capabilities.
            "#
        }
    }
}

TypeScript Map vs Record

map<string, ValueType> generates a Record<string, ValueType> in TypeScript.Other key types (enums, literals) generate a Map<KeyType, ValueType>.
// Generates Record in TypeScript
map<string, string>

// Generates Map in TypeScript
map<Category, string>
map<"A" | "B", string>

Optional Maps

class Config {
    metadata map<string, string>?
}

function ProcessConfig(config: Config) -> string {
    client "openai/gpt-4o-mini"
    prompt #"
        {% if config.metadata %}
        Metadata: {{ config.metadata }}
        {% else %}
        No metadata provided.
        {% endif %}
    "#
}

Generated Types

from typing import Dict, Optional

metadata: Optional[Dict[str, str]] = None
# or
metadata: Optional[Dict[str, str]] = {"key": "value"}

Best Practices

  1. Use string keys for flexible, dynamic data structures
  2. Use enum keys when you have a fixed set of known keys
  3. Use literal string unions for configuration with known environments/modes
  4. Nest maps carefully - deep nesting can make debugging harder
  5. Consider classes instead of maps when structure is well-defined

Build docs developers (and LLMs) love