TypeScript Setup

Matrix UI is built with TypeScript from the ground up, providing complete type safety and excellent IDE support.

Configuration

Recommended TypeScript configuration for Matrix UI projects:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "noEmit": true,
    "incremental": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

Component Types

All Matrix UI components export their prop types for use in your application:

Importing Component Types

import { Button, type ButtonProps } from '@matrix-ui/components'
import { Dialog, type DialogProps } from '@matrix-ui/components'
import { Input, type InputProps } from '@matrix-ui/components'

// Use types in your components
interface CustomButtonProps extends ButtonProps {
  customProp?: string
}

const CustomButton: React.FC<CustomButtonProps> = ({ 
  customProp, 
  ...props 
}) => {
  return <Button {...props} />
}

Variant Types

Components with variants export their variant types:

import { type VariantProps } from 'class-variance-authority'
import { buttonVariants } from '@matrix-ui/components'

type ButtonVariants = VariantProps<typeof buttonVariants>

// Access specific variant types
type ButtonVariant = ButtonVariants['variant']  
// "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"

type ButtonSize = ButtonVariants['size']
// "default" | "sm" | "lg" | "icon"

Ref Forwarding

All components properly forward refs with correct typing:

import { useRef } from 'react'
import { Button, Input } from '@matrix-ui/components'

function MyComponent() {
  const buttonRef = useRef<HTMLButtonElement>(null)
  const inputRef = useRef<HTMLInputElement>(null)
  
  return (
    <>
      <Button ref={buttonRef}>Click me</Button>
      <Input ref={inputRef} placeholder="Type here" />
    </>
  )
}

Utility Types

Matrix UI exports utility types for common patterns:

Component Props Utilities

// Extract props from any component
import { ComponentProps } from 'react'
import { Card } from '@matrix-ui/components'

type CardProps = ComponentProps<typeof Card>
type CardHeaderProps = ComponentProps<typeof Card.Header>
type CardContentProps = ComponentProps<typeof Card.Content>

Polymorphic Components

Components using the asChild prop maintain proper typing:

import { Button } from '@matrix-ui/components'
import Link from 'next/link'

// Button renders as Link with proper typing
<Button asChild>
  <Link href="/about">About</Link>
</Button>

// Custom component with asChild
<Dialog.Trigger asChild>
  <button className="custom-button">Open Dialog</button>
</Dialog.Trigger>

Event Handlers

All event handlers are properly typed:

import { Input, Button, Checkbox } from '@matrix-ui/components'
import { type ChangeEvent, type MouseEvent } from 'react'

function Form() {
  const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value)
  }
  
  const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()
  }
  
  const handleCheckedChange = (checked: boolean) => {
    console.log('Checked:', checked)
  }
  
  return (
    <>
      <Input onChange={handleInputChange} />
      <Button onClick={handleClick}>Submit</Button>
      <Checkbox onCheckedChange={handleCheckedChange} />
    </>
  )
}

Shared Configuration

Matrix UI provides shared TypeScript configurations you can extend:

// Extend Matrix UI's base configuration
{
  "extends": "@matrix-ui/tsconfig/base.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

// For Next.js projects
{
  "extends": "@matrix-ui/tsconfig/nextjs.json",
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

// For React libraries
{
  "extends": "@matrix-ui/tsconfig/react-library.json",
  "include": ["src"],
  "exclude": ["dist", "node_modules"]
}

IDE Support

IntelliSense

Matrix UI provides comprehensive IntelliSense support:

  • Prop suggestions and documentation
  • Variant autocomplete
  • Event handler signatures
  • Import suggestions

Type Checking

Enable type checking in your development workflow:

// package.json
{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "typecheck:watch": "tsc --noEmit --watch"
  }
}

Common Patterns

Extending Component Props

import { Button, type ButtonProps } from '@matrix-ui/components'
import { type ReactNode } from 'react'

interface IconButtonProps extends Omit<ButtonProps, 'children'> {
  icon: ReactNode
  label: string
}

function IconButton({ icon, label, ...props }: IconButtonProps) {
  return (
    <Button {...props} aria-label={label}>
      {icon}
    </Button>
  )
}

Generic Components

import { Select } from '@matrix-ui/components'

interface Option<T> {
  value: T
  label: string
}

interface TypedSelectProps<T> {
  options: Option<T>[]
  value?: T
  onChange?: (value: T) => void
}

function TypedSelect<T extends string>({ 
  options, 
  value, 
  onChange 
}: TypedSelectProps<T>) {
  return (
    <Select value={value} onValueChange={onChange}>
      <Select.Trigger>
        <Select.Value />
      </Select.Trigger>
      <Select.Content>
        {options.map((option) => (
          <Select.Item key={option.value} value={option.value}>
            {option.label}
          </Select.Item>
        ))}
      </Select.Content>
    </Select>
  )
}

Troubleshooting

  • Ensure strict: true is enabled for best type safety
  • Use skipLibCheck: true to improve build performance
  • Set moduleResolution: "bundler" for modern module resolution
  • Enable incremental: true for faster subsequent builds