TypeScript Development
Build sophisticated tools using TypeScript that extend your agents' capabilities. This guide covers development setup, best practices, and patterns for creating reliable, performant, and secure tools.
Quick Start
Get up and running with TypeScript tool development in minutes:
Set up your project structure
Create the recommended directory layout with organized tool files, type definitions, and configuration files for maintainable development.
Configure TypeScript for Bun
Set up TypeScript compiler options optimized for Bun's runtime environment with modern ES features and strict type checking.
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true,
"isolatedModules": true
}
}
Install essential dependencies
Add Zod for runtime validation and TypeScript development dependencies to ensure type safety and robust error handling.
bun add zod # Runtime validation
bun add -d typescript @types/node
Create your first tool
Build a simple greeting tool with Zod schema validation, multi-language support, and proper TypeScript typing as a foundation.
// tools/greeting.ts
import { z } from 'zod';
const inputSchema = z.object({
name: z.string(),
language: z.enum(['en', 'es', 'fr']).default('en')
});
type Input = z.infer<typeof inputSchema>;
export async function greeting(input: Input) {
const { name, language } = inputSchema.parse(input);
const greetings = {
en: `Hello, ${name}!`,
es: `¡Hola, ${name}!`,
fr: `Bonjour, ${name}!`
};
return {
message: greetings[language],
timestamp: new Date().toISOString()
};
}
Core Development Patterns
Tool Export Patterns
Export tools as a structured object:
// tools/index.ts
import { greeting } from './greeting';
import { dataProcessor } from './data-processor';
import { apiClient } from './api-client';
// Export all tools in organized object
export default {
// Utility tools
greeting,
// Data processing
'data-processor': dataProcessor,
'data-validator': dataValidator,
// External integrations
'api-client': apiClient,
'webhook-handler': webhookHandler
};
Testing Your Tools
Write comprehensive tests to ensure reliability:
// tests/greeting.test.ts
import { describe, it, expect } from 'bun:test';
import { greeting } from '../tools/greeting';
describe('Greeting Tool', () => {
it('should generate English greeting by default', async () => {
const result = await greeting({ name: 'Alice' });
expect(result.message).toBe('Hello, Alice!');
expect(result.timestamp).toBeDefined();
});
it('should support multiple languages', async () => {
const spanish = await greeting({ name: 'Carlos', language: 'es' });
const french = await greeting({ name: 'Marie', language: 'fr' });
expect(spanish.message).toBe('¡Hola, Carlos!');
expect(french.message).toBe('Bonjour, Marie!');
});
it('should validate input schema', async () => {
expect(async () => {
await greeting({ name: 123 } as any); // Invalid input
}).toThrow();
});
});
// Integration test with mocked dependencies
describe('API Client Tool', () => {
it('should handle successful API calls', async () => {
// Mock fetch globally for Bun
globalThis.fetch = async () => new Response(
JSON.stringify({ success: true, data: 'test' }),
{ status: 200 }
);
const result = await apiClient({
url: 'https://api.example.com/test',
method: 'GET'
});
expect(result.data).toEqual({ success: true, data: 'test' });
});
});
Debugging and Development
Best Practices
Type Safety First
Error Boundaries
Performance Aware
Built-in Testing
- Single Responsibility
Each tool should focus on one specific operation or domain
- Input Validation
Always validate inputs using Zod schemas with descriptive error messages
- Resource Management
Set appropriate timeouts and handle cleanup properly
- Error Handling
Use structured error responses that agents can understand and act upon
- Documentation
Include JSDoc comments for complex functions and type definitions
- Testing
Write unit tests for all tools and integration tests for complex workflows