TypeScript type definitions and interfaces for the FoundryKit ecosystem. Provides shared types across all FoundryKit packages for consistent type safety.
- Shared types - Common types used across all FoundryKit packages
- Component types - TypeScript interfaces for component props and configurations
- Registry types - Types for component registry and metadata
- Utility types - Helper types for common patterns
-
Strict typing - Comprehensive type safety with no
any
types
pnpm add @foundrykit/types
Configuration interface for components:
import type { ComponentConfig } from '@foundrykit/types';
interface ComponentConfig {
name: string;
description?: string;
category: 'primitives' | 'components' | 'blocks';
variants?: ComponentVariant[];
props?: ComponentProp[];
examples?: ComponentExample[];
}
Variant configuration for components:
import type { ComponentVariant } from '@foundrykit/types';
interface ComponentVariant {
name: string;
description?: string;
props?: Record<string, any>;
className?: string;
}
Property definition for components:
import type { ComponentProp } from '@foundrykit/types';
interface ComponentProp {
name: string;
type: string;
required?: boolean;
default?: any;
description?: string;
}
Component metadata for the registry:
import type { RegistryComponent } from '@foundrykit/types';
interface RegistryComponent {
id: string;
name: string;
description: string;
category: string;
tags: string[];
version: string;
author: string;
dependencies: string[];
files: RegistryFile[];
preview?: string;
}
File information for registry components:
import type { RegistryFile } from '@foundrykit/types';
interface RegistryFile {
name: string;
path: string;
content: string;
type: 'component' | 'config' | 'readme' | 'test';
}
Make all properties in an object optional recursively:
import type { DeepPartial } from '@foundrykit/types';
type UserConfig = {
name: string;
settings: {
theme: string;
notifications: boolean;
};
};
type PartialUserConfig = DeepPartial<UserConfig>;
// Equivalent to:
// {
// name?: string
// settings?: {
// theme?: string
// notifications?: boolean
// }
// }
Extract keys that are required from an object type:
import type { RequiredKeys } from '@foundrykit/types';
type User = {
id: string;
name?: string;
email?: string;
};
type RequiredUserKeys = RequiredKeys<User>; // "id"
Extract keys that are optional from an object type:
import type { OptionalKeys } from '@foundrykit/types';
type User = {
id: string;
name?: string;
email?: string;
};
type OptionalUserKeys = OptionalKeys<User>; // "name" | "email"
import type { ComponentConfig, ComponentVariant } from '@foundrykit/types';
// Define component configuration
const buttonConfig: ComponentConfig = {
name: 'Button',
description: 'Accessible button component',
category: 'primitives',
variants: [
{
name: 'default',
description: 'Default button variant',
className: 'bg-blue-500 text-white',
},
{
name: 'outline',
description: 'Outline button variant',
className: 'border border-gray-300 bg-transparent',
},
],
props: [
{
name: 'children',
type: 'ReactNode',
required: true,
description: 'Button content',
},
{
name: 'variant',
type: '"default" | "outline"',
default: 'default',
description: 'Button variant',
},
],
};
import type { RegistryComponent, RegistryFile } from '@foundrykit/types';
// Define registry component
const buttonRegistry: RegistryComponent = {
id: 'button',
name: 'Button',
description: 'Accessible button component with multiple variants',
category: 'primitives',
tags: ['react', 'accessible', 'ui'],
version: '1.0.0',
author: 'FoundryKit Team',
dependencies: ['react', '@foundrykit/primitives'],
files: [
{
name: 'index.tsx',
path: 'components/button/index.tsx',
content: '...',
type: 'component',
},
{
name: 'config.ts',
path: 'components/button/config.ts',
content: '...',
type: 'config',
},
],
preview: 'data:image/svg+xml;base64,...',
};
import type { ComponentProp } from '@foundrykit/types';
// Define component props
const buttonProps: ComponentProp[] = [
{
name: 'children',
type: 'ReactNode',
required: true,
description: 'Button content',
},
{
name: 'variant',
type: '"default" | "outline" | "ghost"',
default: 'default',
description: 'Visual variant of the button',
},
{
name: 'size',
type: '"sm" | "md" | "lg"',
default: 'md',
description: 'Size of the button',
},
{
name: 'disabled',
type: 'boolean',
default: false,
description: 'Whether the button is disabled',
},
];
import type {
DeepPartial,
RequiredKeys,
OptionalKeys,
} from '@foundrykit/types';
// Deep partial example
type UserSettings = {
theme: {
mode: 'light' | 'dark';
primary: string;
};
notifications: {
email: boolean;
push: boolean;
};
};
type PartialSettings = DeepPartial<UserSettings>;
// All properties are now optional recursively
// Required keys example
type FormData = {
email: string;
password: string;
name?: string;
age?: number;
};
type RequiredFields = RequiredKeys<FormData>; // "email" | "password"
// Optional keys example
type OptionalFields = OptionalKeys<FormData>; // "name" | "age"
import type { ComponentConfig } from '@foundrykit/types';
// Generic component configuration
interface GenericComponentConfig<TProps = any> extends ComponentConfig {
props: Array<{
name: keyof TProps;
type: string;
required?: boolean;
default?: any;
description?: string;
}>;
}
// Usage
type ButtonProps = {
children: ReactNode;
variant: 'default' | 'outline';
size: 'sm' | 'md' | 'lg';
};
const buttonConfig: GenericComponentConfig<ButtonProps> = {
name: 'Button',
category: 'primitives',
props: [
{
name: 'children',
type: 'ReactNode',
required: true,
},
{
name: 'variant',
type: '"default" | "outline"',
default: 'default',
},
{
name: 'size',
type: '"sm" | "md" | "lg"',
default: 'md',
},
],
};
import type { ComponentConfig } from '@foundrykit/types';
// Conditional type based on category
type CategorySpecificConfig<T extends ComponentConfig['category']> =
T extends 'primitives'
? ComponentConfig & {
accessibility: boolean;
unstyled: boolean;
}
: T extends 'components'
? ComponentConfig & {
styled: boolean;
themeable: boolean;
}
: ComponentConfig & {
responsive: boolean;
seo: boolean;
};
// Usage
const primitiveConfig: CategorySpecificConfig<'primitives'> = {
name: 'Button',
category: 'primitives',
accessibility: true,
unstyled: true,
// ... other required properties
};
import type { ComponentConfig, RegistryComponent } from '@foundrykit/types';
// Type guard for component config
function isComponentConfig(obj: any): obj is ComponentConfig {
return (
typeof obj === 'object' &&
typeof obj.name === 'string' &&
typeof obj.category === 'string' &&
['primitives', 'components', 'blocks'].includes(obj.category)
);
}
// Type guard for registry component
function isRegistryComponent(obj: any): obj is RegistryComponent {
return (
typeof obj === 'object' &&
typeof obj.id === 'string' &&
typeof obj.name === 'string' &&
Array.isArray(obj.tags) &&
typeof obj.version === 'string'
);
}
// Usage
function processComponent(data: unknown) {
if (isComponentConfig(data)) {
// TypeScript knows this is a ComponentConfig
console.log(`Processing component: ${data.name}`);
} else if (isRegistryComponent(data)) {
// TypeScript knows this is a RegistryComponent
console.log(`Processing registry component: ${data.id}`);
}
}
When adding new types:
- Follow TypeScript best practices
- Use strict typing (avoid
any
) - Add JSDoc documentation
- Include usage examples
- Update this README
- Ensure backward compatibility
MIT