Type Inference
How Bunli provides automatic type inference for your CLI
Type Inference
Bunli provides automatic type inference through a unified type system that combines runtime validation with compile-time type safety. By using as const on command names and leveraging module augmentation, you get full type safety with zero manual type annotations.
How It Works
Bunli uses a revolutionary approach that combines:
- Module Augmentation - Generated types automatically extend the core type system
- Command Name Literals - Using
as constenables automatic type inference - Standard Schema Integration - Built-in type extraction from validation schemas
- Zero Manual Annotations - Handlers are automatically typed based on command names
The Magic: Automatic Type Inference
When you define a command with as const, the handler automatically gets the correct types:
export default defineCommand({
name: 'deploy' as const, // ← REQUIRED: 'as const' enables type inference
description: 'Deploy the application',
options: {
env: option(z.enum(['dev', 'staging', 'prod']), {
description: 'Environment to deploy to'
}),
dryRun: option(z.boolean().default(false), {
description: 'Run without making changes'
})
},
// ✨ NO TYPE ANNOTATION NEEDED! ✨
// flags is automatically typed as { env: 'dev' | 'staging' | 'prod', dryRun: boolean }
handler: async ({ flags }) => {
console.log(`Deploying to ${flags.env}`) // ← Full autocomplete!
if (flags.dryRun) {
console.log('Dry run mode')
}
}
})Requirements
To use Bunli's automatic type inference, you need:
as constRequired - Command names MUST useas constfor type inference- Generated File Required -
.bunli/commands.gen.tsmust be intsconfig.json - Type Generation Required - Codegen must be enabled
- No Manual Annotations - Handler type annotations are automatic
Command Definition Pattern
Correct Pattern
export default defineCommand({
name: 'deploy' as const, // ✅ 'as const' required
options: { ... },
handler: async ({ flags }) => { // ✅ No annotation needed!
// flags is automatically typed!
}
})Incorrect Pattern
export default defineCommand({
name: 'deploy', // ❌ No 'as const' - no type inference
options: { ... },
handler: async ({ flags }: { flags: { env: string } }) => { // ❌ Manual annotation not needed
// ...
}
})Type-Safe Command Execution
With generated types, you can execute commands programmatically with full type safety:
import { createCLI } from '@bunli/core'
const cli = await createCLI(config)
// ✅ Fully type-safe!
await cli.execute('deploy', {
env: 'production', // ← Autocomplete: 'dev' | 'staging' | 'prod'
dryRun: true // ← Type: boolean
})
// ❌ Type errors!
await cli.execute('deploy', {
env: 'invalid', // ❌ Error: Type '"invalid"' is not assignable
dryRun: 'yes' // ❌ Error: Type 'string' is not assignable to type 'boolean'
})Command Discovery
Generated types provide helper functions for type-safe command discovery:
import { listCommands, getCommandApi, hasCommand } from './commands.gen'
// List all commands
const commands = listCommands()
console.log(`Total commands: ${commands.length}`)
// Type-safe command lookup
if (hasCommand('deploy')) {
const deployApi = getCommandApi('deploy')
// deployApi is fully typed!
}Advanced Type Utilities
Bunli exports advanced TypeScript type utilities for complex type manipulation:
import {
UnionToIntersection,
MergeAll,
Expand,
DeepPartial,
Constrain
} from '@bunli/core'
// Get all command options as a union
type AllCommandOptions = UnionToIntersection<
ReturnType<typeof getCommandApi>[keyof CommandRegistry]['options']
>
// Merge all command metadata
type AllCommands = MergeAll<
Array<{ name: string; description: string }>
>Configuration
Enable type generation in your bunli.config.ts:
export default defineConfig({
name: 'my-cli',
version: '1.0.0',
})Generated File Structure
The .bunli/commands.gen.ts file contains:
CommandsByNameinterface - Maps command names to their definitionsRegisteredCommandsmodule augmentation - Extends @bunli/core types- Helper functions -
getCommandApi,listCommands,hasCommand - Runtime registry - For command discovery
See Also
- Type Generation Guide - Complete guide to code generation
- Configuration - Configure type generation