Skip to content

JSTC Validation Rules

Learn to validate JavaScript values with different JSTC validation rules and patterns.

Basic Type Validation

Validate primitive types:

typescript
import JSTC from "@briklab/lib/jstc";

// Validate numbers
console.log(JSTC.for([42]).check(["number"])); // true
console.log(JSTC.for(["42"]).check(["number"])); // false

// Validate strings
console.log(JSTC.for(["hello"]).check(["string"])); // true
console.log(JSTC.for([42]).check(["string"])); // false

// Validate booleans
console.log(JSTC.for([true]).check(["boolean"])); // true
console.log(JSTC.for([1]).check(["boolean"])); // false

// Validate undefined
console.log(JSTC.for([undefined]).check(["undefined"])); // true

Live demo of type validation:

Console
No logs yet.

Complex Type Checking

Validate compound types:

typescript
import JSTC from "@briklab/lib/jstc";

// Array validation
console.log(JSTC.for([[1, 2, 3]]).check(["array"])); // true
console.log(JSTC.for(["array"]).check(["array"])); // false

// Object validation
console.log(JSTC.for([{ name: "John" }]).check(["object"])); // true
console.log(JSTC.for([[]]).check(["object"])); // false (arrays are not objects)

// Function validation
console.log(JSTC.for([() => {}]).check(["function"])); // true
console.log(JSTC.for([{}]).check(["function"])); // false

Multiple Type Alternatives

Allow multiple valid types:

typescript
import JSTC from "@briklab/lib/jstc";

// Value can be string or number
console.log(JSTC.for(["test"]).check(["string"])); // true
console.log(JSTC.for([42]).check(["number"])); // true
console.log(JSTC.for([true]).check(["string"])); // false

// Value can be number, undefined, or null
console.log(JSTC.for([0]).check(["number"])); // true
console.log(JSTC.for([undefined]).check(["undefined"])); // true
console.log(JSTC.for(["0"]).check(["number"])); // false

// Multiple values with independent types
console.log(JSTC.for([42, "hello", false]).check(["number", "string", "boolean"])); // true

Array Element Validation

Validate arrays of specific types:

typescript
import JSTC from "@briklab/lib/jstc";

// Array of numbers
console.log(JSTC.for([[1, 2, 3]]).check(["array"])); // true
console.log(JSTC.for([[1, "2", 3]]).check(["array"])); // still true (checks if it's an array)

// Manual validation of array elements
function validateNumberArray(arr: any): boolean {
  if (!Array.isArray(arr)) return false;
  return arr.every((item) => JSTC.for([item]).check(["number"]));
}

console.log(validateNumberArray([1, 2, 3])); // true
console.log(validateNumberArray([1, "2", 3])); // false

Object Property Validation

Validate object structure:

typescript
import JSTC from "@briklab/lib/jstc";

interface User {
  name: string;
  age: number;
  email?: string;
}

function validateUserObject(obj: any): obj is User {
  if (!JSTC.for([obj]).check(["object"])) return false;
  if (!JSTC.for([obj.name]).check(["string"])) return false;
  if (!JSTC.for([obj.age]).check(["number"])) return false;
  if (obj.email !== undefined && !JSTC.for([obj.email]).check(["string"])) {
    return false;
  }
  return true;
}

const user: any = {
  name: "John",
  age: 30,
  email: "john@example.com"
};

console.log(validateUserObject(user)); // true

Nested Validation

Check deeply nested structures:

typescript
import JSTC from "@briklab/lib/jstc";

interface Blog {
  title: string;
  author: {
    name: string;
    email: string;
  };
  tags: string[];
}

function validateBlog(obj: any): obj is Blog {
  // Check root
  if (!JSTC.for([obj]).check(["object"])) return false;
  if (!JSTC.for([obj.title]).check(["string"])) return false;

  // Check author
  if (!JSTC.for([obj.author]).check(["object"])) return false;
  if (!JSTC.for([obj.author.name]).check(["string"])) return false;
  if (!JSTC.for([obj.author.email]).check(["string"])) return false;

  // Check tags
  if (!JSTC.for([obj.tags]).check(["array"])) return false;
  if (!obj.tags.every((tag: any) => JSTC.for([tag]).check(["string"]))) return false;

  return true;
}

Conditional Validation

Validate based on conditions:

typescript
import JSTC  from "@briklab/lib/jstc";

interface APIResponse {
  success: boolean;
  data?: any;
  error?: string;
}

function validateAPIResponse(response: any): response is APIResponse {
  if (!JSTC.for([response]).check(["object"])) return false;
  if (!JSTC.for([response.success]).check(["boolean"])) return false;

  if (response.success) {
    // If success, data should exist
    return response.data !== undefined;
  } else {
    // If not success, error message should exist
    return JSTC.for([response.error]).check(["string"]);
  }
}

Union Type Validation

Handle union types:

typescript
import JSTC from "@briklab/lib/jstc";

type ID = string | number;

function validateID(value: any): value is ID {
  return JSTC.for([value]).check(["string", "number"]);
}

console.log(validateID("user-123")); // true
console.log(validateID(42)); // true
console.log(validateID(true)); // false

Enum Validation

Validate against enum values:

typescript
import JSTC from "@briklab/lib/jstc";

enum Status {
  Active = "active",
  Inactive = "inactive",
  Pending = "pending"
}

function validateStatus(value: any): value is Status {
  const validStatuses = Object.values(Status);
  return validStatuses.includes(value);
}

console.log(validateStatus("active")); // true
console.log(validateStatus("invalid")); // false

Custom Validation Rules

Create reusable validation patterns:

typescript
import JSTC from "@briklab/lib/jstc";

class ValidationRules {
  static isEmail(value: any): boolean {
    if (!JSTC.for([value]).check(["string"])) return false;
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(value);
  }

  static isURL(value: any): boolean {
    if (!JSTC.for([value]).check(["string"])) return false;
    try {
      new URL(value);
      return true;
    } catch {
      return false;
    }
  }

  static isPhoneNumber(value: any): boolean {
    if (!JSTC.for([value]).check(["string"])) return false;
    const phoneRegex = /^\d{10}$/;
    return phoneRegex.test(value.replace(/\D/g, ""));
  }

  static isStrongPassword(value: any): boolean {
    if (!JSTC.for([value]).check(["string"])) return false;
    return (
      value.length >= 8 &&
      /[A-Z]/.test(value) &&
      /[a-z]/.test(value) &&
      /\d/.test(value)
    );
  }
}

// Usage
console.log(ValidationRules.isEmail("user@example.com")); // true
console.log(ValidationRules.isStrongPassword("MyPassw0rd123")); // true

Validation Collections

Validate multiple values at once:

typescript
import JSTC from "@briklab/lib/jstc";

class BatchValidation {
  static validateAll(
    values: any[],
    types: (string | string[])[]
  ): boolean {
    if (values.length !== types.length) return false;

    return values.every((value, index) =>
      JSTC.for([value]).check([types[index]])
    );
  }

  static validateObject(obj: any, schema: Record<string, string>): boolean {
    if (!JSTC.for([obj]).check(["object"])) return false;

    return Object.entries(schema).every(([key, type]) =>
      JSTC.for([obj[key]]).check([type])
    );
  }
}

// Usage
const isValid = BatchValidation.validateAll(
  [42, "hello", true],
  ["number", "string", "boolean"]
); // true

const userData = { name: "John", age: 30 };
const isUserValid = BatchValidation.validateObject(userData, {
  name: "string",
  age: "number"
}); // true

Next Steps