Skip to content

Rule Inheritance

Rule inheritance lets you create specialized rules that extend existing ones. This promotes code reuse and keeps your validation DRY.

Basic Inheritance

Use inheritRule to create a child rule:

ts
import { inheritRule, lengthRule, addRules } from '@pliant/core';

addRules(registry, {
  // Base rule
  length: lengthRule({ min: 0, max: 256 }),
  
  // Inherited rules
  username: inheritRule('length', {
    options: { min: 3, max: 20 }
  }),
  password: inheritRule('length', {
    options: { min: 8, max: 64 }
  }),
  bio: inheritRule('length', {
    options: { max: 500 }
  })
});

What Gets Inherited

When a rule inherits from a parent:

  1. Options are merged - Child options override parent options
  2. Validation logic is reused - The parent's validate function runs
  3. Messages can be overridden - Or inherited from parent
ts
// Parent rule
addRules(registry, {
  length: lengthRule({ min: 0, max: 256 })
});

// Child with custom message
addRules(registry, {
  tweetLength: inheritRule('length', {
    options: { max: 280 },
    message: 'Tweet exceeds 280 characters'
  })
});

Inheritance Chain

Rules can inherit from inherited rules:

ts
addRules(registry, {
  // Base
  length: lengthRule({ min: 0, max: 256 }),
  
  // First level
  textField: inheritRule('length', {
    options: { max: 1000 }
  }),
  
  // Second level
  shortText: inheritRule('textField', {
    options: { max: 100 }
  }),
  longText: inheritRule('textField', {
    options: { max: 5000 }
  })
});

Built-in Inheritance

Some built-in rules use inheritance internally:

ts
// minLength inherits from length
import { minLengthRule } from '@pliant/core';
const minLength = minLengthRule({ min: 8 });
// Equivalent to: inheritRule('length', { options: { min: 8 } })

// maxLength inherits from length
import { maxLengthRule } from '@pliant/core';
const maxLength = maxLengthRule({ max: 100 });
// Equivalent to: inheritRule('length', { options: { max: 100 } })

WARNING

When using minLengthRule or maxLengthRule, you must also register the base length rule:

ts
addRules(registry, {
  length: lengthRule({ min: 0, max: 256 }), // Required!
  password: minLengthRule({ min: 8 })
});

Use Cases

Domain-Specific Rules

ts
addRules(registry, {
  // Base rules
  length: lengthRule(),
  range: rangeRule(),
  
  // Domain: User Profile
  username: inheritRule('length', { options: { min: 3, max: 20 } }),
  displayName: inheritRule('length', { options: { min: 1, max: 50 } }),
  bio: inheritRule('length', { options: { max: 500 } }),
  age: inheritRule('range', { options: { min: 13, max: 120 } }),
  
  // Domain: E-commerce
  productName: inheritRule('length', { options: { min: 3, max: 100 } }),
  productDescription: inheritRule('length', { options: { max: 2000 } }),
  price: inheritRule('range', { options: { min: 0, max: 99999 } }),
  quantity: inheritRule('range', { options: { min: 1, max: 999 } })
});

Environment-Specific Rules

ts
const isDev = process.env.NODE_ENV === 'development';

addRules(registry, {
  password: lengthRule({ 
    min: isDev ? 4 : 8,  // Relaxed in dev
    max: 64 
  })
});

Feature Flags

ts
addRules(registry, {
  username: inheritRule('length', {
    options: { 
      min: 3, 
      max: featureFlags.longUsernames ? 50 : 20 
    }
  })
});

Released under the MIT License.