Skip to content

TypeScript Support

Ctrovalidate is written in TypeScript and includes comprehensive type definitions. All types are exported from the main package.


Installation

Type definitions are included automatically when you install Ctrovalidate:

bash
npm install ctrovalidate

No separate @types package is needed.


Basic Usage

Importing Types

typescript
import { 
  Ctrovalidate, 
  type CtrovalidateOptions,
  type RuleLogic,
  type AsyncRuleLogic
} from 'ctrovalidate';

Type-Safe Initialization

typescript
const form = document.querySelector<HTMLFormElement>('#myForm')!;

const options: CtrovalidateOptions = {
  realTime: true,
  logLevel: LogLevel.DEBUG,
  errorClass: 'is-invalid',
  errorMessageClass: 'error-message',
  pendingClass: 'is-validating'
};

const validator = new Ctrovalidate(form, options);

Type Definitions

CtrovalidateOptions

Configuration options for the validator instance.

typescript
import { LogLevel } from 'ctrovalidate';

interface CtrovalidateOptions {
  realTime?: boolean;           // Default: true
  logLevel?: LogLevel;          // Default: LogLevel.NONE (0)
  errorClass?: string;          // Default: 'is-invalid'
  errorMessageClass?: string;   // Default: 'error-message'
  pendingClass?: string;        // Default: 'ctrovalidate-pending'
}

LogLevel Enum:

typescript
enum LogLevel {
  NONE = 0,   // No logging (production)
  ERROR = 1,  // Critical errors only
  WARN = 2,   // Warnings and errors
  INFO = 3,   // Info, warnings, and errors
  DEBUG = 4   // All messages (development)
}

RuleLogic

Function signature for synchronous validation rules.

typescript
type RuleLogic = (
  value: string,
  params: string[],
  element: HTMLElement
) => boolean;

Example:

typescript
const isPositive: RuleLogic = (value, params, element) => {
  return parseFloat(value) > 0;
};

Ctrovalidate.addRule('isPositive', isPositive, 'Must be positive.');

AsyncRuleLogic

Function signature for asynchronous validation rules.

typescript
type AsyncRuleLogic = (
  value: string,
  params: string[],
  element: HTMLElement,
  signal: AbortSignal
) => Promise<boolean>;

Example:

typescript
const checkUsername: AsyncRuleLogic = async (value, params, element, signal) => {
  const response = await fetch(`/api/check?username=${value}`, { signal });
  const data = await response.json();
  return data.available;
};

Ctrovalidate.addAsyncRule('usernameAvailable', checkUsername, 'Username taken.');

FieldObject (Internal)

Internal type representing a tracked field. Not typically used in application code.

typescript
interface FieldObject {
  element: HTMLElement;
  rules: ParsedRule[];
  dependency: Dependency | null;
  state: {
    isDirty: boolean;
    abortController: AbortController | null;
    lastError: string | null;
  };
}

Framework Integration

React with TypeScript

typescript
import { useEffect, useRef } from 'react';
import { Ctrovalidate, LogLevel, type CtrovalidateOptions } from 'ctrovalidate';

function MyForm() {
  const formRef = useRef<HTMLFormElement>(null);
  const validatorRef = useRef<Ctrovalidate | null>(null);

  useEffect(() => {
    if (!formRef.current) return;

    const options: CtrovalidateOptions = {
      realTime: true,
      logLevel: LogLevel.WARN
    };

    validatorRef.current = new Ctrovalidate(formRef.current, options);

    return () => {
      validatorRef.current?.destroy();
    };
  }, []);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (validatorRef.current && await validatorRef.current.validate()) {
      // Submit form
    }
  };

  return <form ref={formRef} onSubmit={handleSubmit}>...</form>;
}

Vue 3 with TypeScript

typescript
import { ref, onMounted, onUnmounted } from 'vue';
import { Ctrovalidate, type CtrovalidateOptions } from 'ctrovalidate';

export default {
  setup() {
    const formRef = ref<HTMLFormElement | null>(null);
    let validator: Ctrovalidate | null = null;

    onMounted(() => {
      if (!formRef.value) return;

      const options: CtrovalidateOptions = {
        realTime: true
      };

      validator = new Ctrovalidate(formRef.value, options);
    });

    onUnmounted(() => {
      validator?.destroy();
    });

    const handleSubmit = async () => {
      if (validator && await validator.validate()) {
        // Submit form
      }
    };

    return { formRef, handleSubmit };
  }
};

Custom Rules with Types

Synchronous Rule

typescript
import { Ctrovalidate, type RuleLogic } from 'ctrovalidate';

const minAge: RuleLogic = (value, [age], element) => {
  const numValue = parseInt(value, 10);
  const minAge = parseInt(age, 10);
  return numValue >= minAge;
};

Ctrovalidate.addRule('minAge', minAge, 'Must be at least {0} years old.');

Asynchronous Rule

typescript
import { Ctrovalidate, type AsyncRuleLogic } from 'ctrovalidate';

const checkEmail: AsyncRuleLogic = async (value, params, element, signal) => {
  try {
    const response = await fetch(`/api/check-email?email=${value}`, { signal });
    const data = await response.json();
    return data.available;
  } catch (error) {
    if (error instanceof Error && error.name === 'AbortError') {
      return true; // Request was aborted
    }
    return false; // Network error
  }
};

Ctrovalidate.addAsyncRule('emailAvailable', checkEmail, 'Email already in use.');

Type Reference Summary

TypeDescription
CtrovalidateMain validator class
CtrovalidateOptionsConfiguration options interface
LogLevelEnum for logging levels (0-4)
RuleLogicSynchronous rule function type
AsyncRuleLogicAsynchronous rule function type
FieldObjectInternal field tracking object

Next Steps

Released under the MIT License.