Advanced Type Features

Spectral supports advanced type system features including array types, circular references, and multi-dimensional arrays for building complex data structures.

Array Types

Define arrays of any type using the [] notation. Arrays can be single-dimensional or multi-dimensional.

Single-Dimensional Arrays

type User {
    id: string
    name: string
    email: string
    tags: string[]              // Array of strings
    profileImages: string[]     // Another array
}

type BlogPost {
    id: string
    title: string
    authorId: string
    tags: string[]              // Array of strings
    relatedPostIds: string[]    // Array of post IDs
}
✨ Edit in Studio

Arrays of Custom Types

type Comment {
    id: string
    text: string
    authorId: string
}

type Post {
    id: string
    title: string
    content: string
    comments: Comment[]         // Array of Comment objects
    likes: string[]
}

type User {
    id: string
    name: string
    posts: Post[]               // Array of Post objects
}
✨ Edit in Studio

Multi-Dimensional Arrays

Use multiple [] to create multi-dimensional arrays, perfect for matrices and nested data structures:

type Matrix {
    id: string
    name: string
    data: number[][]            // 2D array (matrix)
    labels: string[]
}

type Tensor {
    id: string
    values: number[][][]        // 3D array
}

type Dataset {
    id: string
    matrices: Matrix[]          // Array of Matrix objects
    metadata: string[]
}
✨ Edit in Studio

Circular References

Spectral supports circular references, allowing types to reference themselves or each other. This is essential for modeling real-world relationships like social networks, organizational hierarchies, and linked data structures.

Self-Referencing Types

Create recursive data structures by having a type reference itself:

type TreeNode {
    id: string
    value: string
    parent: TreeNode            // Reference to parent node
    children: TreeNode[]        // Array of child nodes
}

type Category {
    id: string
    name: string
    parentCategory: Category    // Self-reference
    subcategories: Category[]   // Array of subcategories
}
✨ Edit in Studio

Mutual References

Types can reference each other, creating bidirectional relationships:

type User {
    id: string
    name: string
    email: string
    posts: Post[]               // User references Post
    comments: Comment[]         // User references Comment
}

type Post {
    id: string
    title: string
    content: string
    author: User                // Post references User back
    comments: Comment[]         // Post references Comment
}

type Comment {
    id: string
    text: string
    author: User                // Comment references User
    post: Post                  // Comment references Post back
}
✨ Edit in Studio

Complex Circular Relationships

Build sophisticated data models with multiple circular references:

type Organization {
    id: string
    name: string
    departments: Department[]
    employees: Employee[]
}

type Department {
    id: string
    name: string
    organization: Organization  // Back reference
    employees: Employee[]
    manager: Employee
}

type Employee {
    id: string
    name: string
    department: Department      // Reference to department
    organization: Organization  // Reference to organization
    directReports: Employee[]   // Self-reference for hierarchy
    manager: Employee           // Self-reference for reporting
}
✨ Edit in Studio

Code Generation

TypeScript Output

Spectral generates type-safe TypeScript interfaces with proper array and reference types:

// From: tags: string[]
export interface User {
  id: string;
  name: string;
  tags: string[];           // TypeScript array
  posts: Post[];            // Array of Post interface
}

// From: data: number[][]
export interface Matrix {
  id: string;
  data: number[][];         // 2D TypeScript array
}

// Circular references work naturally in TypeScript
export interface Post {
  author: User;             // TypeScript handles circular refs
  comments: Comment[];
}

Python Output

Python generation uses type hints with List from typing and forward references:

from __future__ import annotations  # Enables forward references
from typing import List
from dataclasses import dataclass

@dataclass
class User:
    id: str
    name: str
    tags: List[str]           # Python List type hint
    posts: List[Post]         # Forward reference to Post

@dataclass
class Matrix:
    id: str
    data: List[List[int]]     # Nested List for 2D array

@dataclass
class Post:
    author: User              # Circular reference works with annotations
    comments: List[Comment]

The from __future__ import annotations enables lazy evaluation of type hints, making circular references work seamlessly in Python.

Best Practices

1. Use Arrays for Collections

type Playlist {
    id: string
    name: string
    trackIds: string[]        // ✓ Good: Clear collection
    tags: string[]
}
✨ Edit in Studio

2. Model Real Relationships

type Book {
    id: string
    title: string
    author: Author
    chapters: Chapter[]       // ✓ Good: Natural relationship
}

type Author {
    id: string
    name: string
    books: Book[]             // ✓ Good: Bidirectional relationship
}
✨ Edit in Studio

3. Use Multi-Dimensional Arrays for Structured Data

type Image {
    id: string
    pixels: number[][]        // ✓ Good: 2D pixel data
    width: number
    height: number
}

type GameBoard {
    id: string
    cells: string[][]         // ✓ Good: 2D grid
}
✨ Edit in Studio

4. Document Complex Circular References

When using circular references, consider adding comments to clarify relationships:

type User {
    id: string
    posts: Post[]             // User's authored posts
}

type Post {
    id: string
    author: User              // Post's author (circular ref)
}
✨ Edit in Studio

Syntax Reference

Array Type Syntax

fieldName: TypeName[]         // Single-dimensional array
fieldName: TypeName[][]       // Two-dimensional array
fieldName: TypeName[][][]     // Three-dimensional array
✨ Edit in Studio

Valid Array Types

  • Primitive types: string[], number[], boolean[], datetime[]
  • Custom types: User[], Post[], Comment[]
  • Enum types: Status[], Role[]
  • Nested arrays: string[][], User[][]

Examples

Social Network

type User {
    id: string
    username: string
    email: string
    followers: User[]         // Array of users following this user
    following: User[]         // Array of users this user follows
    posts: Post[]
    likes: Post[]
}

type Post {
    id: string
    content: string
    author: User              // Circular reference to User
    likedBy: User[]           // Array of users who liked this
    comments: Comment[]
}

type Comment {
    id: string
    text: string
    author: User              // Reference to User
    post: Post                // Reference to Post
}
✨ Edit in Studio

File System

type File {
    id: string
    name: string
    content: string
    parent: Directory         // Reference to parent directory
    tags: string[]
}

type Directory {
    id: string
    name: string
    files: File[]             // Array of files
    subdirectories: Directory[]  // Self-reference for nested directories
    parent: Directory         // Self-reference for parent
}
✨ Edit in Studio

E-commerce

type Product {
    id: string
    name: string
    price: number
    categories: Category[]    // Array of categories
    relatedProducts: Product[] // Self-reference
    reviews: Review[]
    images: string[]
}

type Category {
    id: string
    name: string
    products: Product[]       // Back reference
    subcategories: Category[] // Self-reference
}

type Review {
    id: string
    rating: number
    comment: string
    product: Product          // Back reference
    user: User
}
✨ Edit in Studio

Validation

Spectral validates:

  • ✓ Array syntax is correct ([], [][], etc.)
  • ✓ Referenced types exist
  • ✓ Circular references are valid
  • ✓ No infinite recursion in required fields
  • ✓ Type names are valid identifiers

Migration Guide

Upgrading from Simple Types

Before:

type User {
    id: string
    tagList: string
}
✨ Edit in Studio

After:

type User {
    id: string
    tags: string[]            // Now properly typed as array
}
✨ Edit in Studio

Adding Relationships

Before:

type Post {
    id: string
    authorId: string          // Just an ID
}
✨ Edit in Studio

After:

type Post {
    id: string
    author: User              // Now a proper reference
}

type User {
    id: string
    posts: Post[]             // Bidirectional relationship
}
✨ Edit in Studio

See Also