Skip to content

Instantly share code, notes, and snippets.

@mcsee
Last active October 5, 2025 18:39
Show Gist options
  • Select an option

  • Save mcsee/bd6e1bf62f3a6a3e0843bba573cc7638 to your computer and use it in GitHub Desktop.

Select an option

Save mcsee/bd6e1bf62f3a6a3e0843bba573cc7638 to your computer and use it in GitHub Desktop.

Revisions

  1. mcsee revised this gist Oct 5, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions reified.ts
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    // 2. Create a meaningful entity to group them

    class PriceRange {
    constructor(public min: currency, public max: currency) {
    constructor(public min: Currency, public max: Currency) {
    if (min > max) {
    throw new Error(
    `Invalid price range: min (${min}) `+
    @@ -17,7 +17,7 @@ class PriceRange {

    class Interval {
    // 3. Add missing validation rules to fail-fast
    constructor(public start: date, public end: date) {
    constructor(public start: Date, public end: Date) {
    if (start > end) {
    throw new Error(
    `Invalid date range: start (${start.toISOString()}) ` +
  2. mcsee revised this gist Oct 5, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion reified.ts
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ class PriceRange {
    }

    class Interval {
    // 3. Add missing validation rules to fail fast
    // 3. Add missing validation rules to fail-fast
    constructor(public start: date, public end: date) {
    if (start > end) {
    throw new Error(
  3. mcsee revised this gist Oct 5, 2025. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions reified.ts
    Original file line number Diff line number Diff line change
    @@ -4,11 +4,13 @@ class PriceRange {
    constructor(public min: currency, public max: currency) {
    if (min > max) {
    throw new Error(
    `Invalid price range: min (${min}) cannot be greater than max (${max})`
    `Invalid price range: min (${min}) `+
    `cannot be greater than max (${max})`
    );
    }
    if (min < 0) {
    throw new Error(`Invalid price range: min (${min}) cannot be negative`);
    throw new Error(
    `Invalid price range: min (${min}) cannot be negative`);
    }
    }
    }
  4. mcsee revised this gist Oct 5, 2025. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion reified.ts
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,8 @@ class Interval {
    constructor(public start: date, public end: date) {
    if (start > end) {
    throw new Error(
    `Invalid date range: start (${start.toISOString()}) cannot be after end (${end.toISOString()})`
    `Invalid date range: start (${start.toISOString()}) ` +
    `cannot be after end (${end.toISOString()})`
    );
    }
    }
  5. mcsee revised this gist Oct 5, 2025. 1 changed file with 12 additions and 6 deletions.
    18 changes: 12 additions & 6 deletions reified.ts
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    // 2. Create a meaningful entity to group them

    class PriceRange {
    constructor(public min: currency, public max: currency) {
    if (min > max) {
    @@ -11,7 +13,8 @@ class PriceRange {
    }
    }

    class DateRange {
    class Interval {
    // 3. Add missing validation rules to fail fast
    constructor(public start: date, public end: date) {
    if (start > end) {
    throw new Error(
    @@ -24,27 +27,29 @@ class DateRange {
    class HolidaySearchCriteria {
    constructor(
    public priceRange: PriceRange,
    public dateRange: DateRange,
    public destination?: string
    public dateRange: Interval
    ) {}
    }

    function findHolidays(criteria: HolidaySearchCriteria): Holiday[] {
    // 1. Identify multiple parameters of the same type
    // No need to call validate() - already validated in constructors
    // 4. Replace function signatures with the new entity
    const { priceRange, dateRange } = criteria;
    // 5. Adjust all callers to pass the entity
    // 6. Add context-specific names to improve clarity

    return database.query({
    price: { $gte: priceRange.min, $lte: priceRange.max },
    startDate: { $gte: dateRange.start },
    endDate: { $lte: dateRange.end }
    });
    }

    // Usage - validation happens automatically

    try {
    const criteria = new HolidaySearchCriteria(
    new PriceRange(500, 1000), // ✅ Valid
    new DateRange(
    new Inteval(
    new Date('2025-06-01'),
    new Date('2025-06-15')
    )
    @@ -53,6 +58,7 @@ try {
    findHolidays(criteria);

    // ❌ This will throw immediately
    // Great for UI and API validation
    new PriceRange(1000, 500);

    } catch (error) {
  6. mcsee created this gist Oct 5, 2025.
    60 changes: 60 additions & 0 deletions reified.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    class PriceRange {
    constructor(public min: currency, public max: currency) {
    if (min > max) {
    throw new Error(
    `Invalid price range: min (${min}) cannot be greater than max (${max})`
    );
    }
    if (min < 0) {
    throw new Error(`Invalid price range: min (${min}) cannot be negative`);
    }
    }
    }

    class DateRange {
    constructor(public start: date, public end: date) {
    if (start > end) {
    throw new Error(
    `Invalid date range: start (${start.toISOString()}) cannot be after end (${end.toISOString()})`
    );
    }
    }
    }

    class HolidaySearchCriteria {
    constructor(
    public priceRange: PriceRange,
    public dateRange: DateRange,
    public destination?: string
    ) {}
    }

    function findHolidays(criteria: HolidaySearchCriteria): Holiday[] {
    // No need to call validate() - already validated in constructors
    const { priceRange, dateRange } = criteria;

    return database.query({
    price: { $gte: priceRange.min, $lte: priceRange.max },
    startDate: { $gte: dateRange.start },
    endDate: { $lte: dateRange.end }
    });
    }

    // Usage - validation happens automatically
    try {
    const criteria = new HolidaySearchCriteria(
    new PriceRange(500, 1000), // ✅ Valid
    new DateRange(
    new Date('2025-06-01'),
    new Date('2025-06-15')
    )
    );

    findHolidays(criteria);

    // ❌ This will throw immediately
    new PriceRange(1000, 500);

    } catch (error) {
    console.error(error.message);
    }