LINUX.ORG.RU

История изменений

Исправление Nervous, (текущая версия) :

class IntOptional

Честно говоря, я бы лучше что-то подобное запилил именно для валидации, во имя простоты и открытости (в смысле O в SOLID):

/**
 * Throws an error if the value does not satisfy the given predicate.
 * If environment variable MODE is not 'dev', does nothing.
 * @param {function} predicate
 * @param {*} value
 */
const assertType = (predicate, value) => {
    if (process?.env?.MODE !== 'dev') return;
    if (!predicate(value)) {
        throw new Error(
            `type assertion error: value '${value}' does not satisfy type predicate '${predicate}'`
        );
    }
};

// usage example (use `MODE=dev node assert.mjs`)

console.log('mode:', process.env.MODE);

// basic usage

const isNumber = x => !isNaN(x);
const isPositive = x => x > 0;
const isOdd = x => x % 2 !== 0;
const isSmall = x => x < 123;
const isSmallPositiveOddNumber = x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x);

assertType(isSmallPositiveOddNumber, 19);
console.log('19 is a small positive odd number');

try {
    assertType(isSmallPositiveOddNumber, 12);
    console.log('12 is a small positive odd number');
} catch (e) {
    console.log('12 is NOT a small positive odd number:');
    console.log(e.message);
}

// dynamic validation of function arguments and return value
// (in development mode only)

/**
 * Returns the sum of two small positive odd numbers, that
 * should itself be small. In dev mode, throws if the arguments
 * or the return value do not satisfy type constraints.
 * @param {number} x
 * @param {number} y
 */
const myAdd = (x, y) => {
    assertType(isSmallPositiveOddNumber, x);
    assertType(isSmallPositiveOddNumber, y);
    const sum = x + y;
    assertType(isSmall, sum);
    return sum;
};

console.log('adding 11 and 39:');
console.log(myAdd(11, 39));
try {
    console.log('adding 12 and 99:');
    console.log(myAdd(12, 99));
} catch (e) {
    console.log(e.message);
}
try {
    console.log('adding 55 and 77:');
    console.log(myAdd(55, 77));
} catch (e) {
    console.log(e.message);
}
$ MODE=dev node assert.mjs

mode: dev

19 is a small positive odd number
12 is NOT a small positive odd number:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 11 and 39:
50

adding 12 and 99:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 55 and 77:
type assertion error: value '132' does not satisfy type predicate 'x => x < 123'

Исправление Nervous, :

class IntOptional

Честно говоря, я бы лучше что-то подобное запилил именно для валидации, во имя простоты и открытости (в смысле O в SOLID):

/**
 * Throws an error if the value does not satisfy the given predicate.
 * If environment variable MODE is not 'dev', does nothing.
 * @param {function} predicate
 * @param {*} value
 */
const assertType = (predicate, value) => {
    if (process?.env?.MODE !== 'dev') return;
    if (!predicate(value)) {
        throw new Error(
            `type assertion error: value '${value}' does not satisfy type predicate '${predicate}'`
        );
    }
};

// usage example (use `MODE=dev node assert.mjs`)

console.log('mode:', process.env.MODE);

// basic usage

const isNumber = x => !isNaN(x);
const isPositive = x => x > 0;
const isOdd = x => x % 2 !== 0;
const isSmall = x => x < 123;
const isSmallPositiveOddNumber = x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x);

assertType(isSmallPositiveOddNumber, 19);
console.log('19 is a small positive odd number');

try {
    assertType(isSmallPositiveOddNumber, 12);
    console.log('12 is a small positive odd number');
} catch (e) {
    console.log('12 is NOT a small positive odd number:');
    console.log(e.message);
}

// dynamic validation of function arguments and return value
// (in development mode only)

/**
 * Returns the sum of two small positive odd numbers, that
 * should itself be small. Throws if the arguments or the
 * return value do not satisfy type constraints.
 * @param {number} x
 * @param {number} y
 */
const myAdd = (x, y) => {
    assertType(isSmallPositiveOddNumber, x);
    assertType(isSmallPositiveOddNumber, y);
    const sum = x + y;
    assertType(isSmall, sum);
    return sum;
};

console.log('adding 11 and 39:');
console.log(myAdd(11, 39));
try {
    console.log('adding 12 and 99:');
    console.log(myAdd(12, 99));
} catch (e) {
    console.log(e.message);
}
try {
    console.log('adding 55 and 77:');
    console.log(myAdd(55, 77));
} catch (e) {
    console.log(e.message);
}
$ MODE=dev node assert.mjs

mode: dev

19 is a small positive odd number
12 is NOT a small positive odd number:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 11 and 39:
50

adding 12 and 99:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 55 and 77:
type assertion error: value '132' does not satisfy type predicate 'x => x < 123'

Исправление Nervous, :

class IntOptional

Честно говоря, я бы лучше что-то подобное запилил именно для валидации, во имя простоты и открытости (в смысле O в SOLID):

/**
 * Throws an error if the value does not satisfy the given predicate.
 * If environment variable MODE is not 'dev', does nothing.
 * @param {function} predicate
 * @param {*} value
 */
const assertType = (predicate, value) => {
    if (process?.env?.MODE !== 'dev') return;
    if (!predicate(value)) {
        throw new Error(
            `type assertion error: value '${value}' does not satisfy type predicate '${predicate}'`
        );
    }
};

// usage example (use `MODE=dev node assert.mjs`)

console.log('mode:', process.env.MODE);

// basic usage

const isNumber = x => !isNaN(x);
const isPositive = x => x > 0;
const isOdd = x => x % 2 !== 0;
const isSmall = x => x < 123;
const isSmallPositiveOddNumber = x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x);

assertType(isSmallPositiveOddNumber, 19);
console.log('19 is a small positive odd number');

try {
    assertType(isSmallPositiveOddNumber, 12);
    console.log('12 is a small positive odd number');
} catch (e) {
    console.log('12 is NOT a small positive odd number:');
    console.log(e.message);
}

// dynamic validation of function arguments and return value
// (in development mode only)

/**
 * Returns the sum of two small positive odd numbers, that
 * should itself be small. Throws if the arguments or the
 * return value do not satisfy type constraints.
 * @param {number} x
 * @param {number} y
 */
const myAdd = (x, y) => {
    assertType(isSmallPositiveOddNumber, x);
    assertType(isSmallPositiveOddNumber, y);
    const sum = x + y;
    assertType(isSmall, sum);
    return sum;
};

console.log('adding 11 and 39:');
console.log(myAdd(11, 39));
try {
    console.log('adding 12 and 99:');
    console.log(myAdd(12, 99));
} catch (e) {
    console.log(e.message);
}
try {
    console.log('adding 55 and 77:');
    console.log(myAdd(55, 77));
} catch (e) {
    console.log(e.message);
}
$ MODE=dev node assert.mjs

mode: dev
19 is a small positive odd number
12 is NOT a small positive odd number:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 11 and 39:
50

adding 12 and 99:
type assertion error: value '12' does not satisfy type predicate 'x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x)'

adding 55 and 77:
type assertion error: value '132' does not satisfy type predicate 'x => x < 123'

Исходная версия Nervous, :

class IntOptional

Честно говоря, я бы лучше что-то подобное запилил именно для валидации, во имя простоты и открытости (в смысле O в SOLID):

/**
 * Throws an error if the value does not satisfy the given predicate.
 * If environment variable MODE is not 'dev', does nothing.
 * @param {function} predicate
 * @param {*} value
 */
const assertType = (predicate, value) => {
    if (process?.env?.MODE !== 'dev') return;
    if (!predicate(value)) {
        throw new Error(
            `type assertion error: value '${value}' does not satisfy type predicate '${predicate}'`
        );
    }
};

// usage example (use `MODE=dev node assert.mjs`)

console.log('mode:', process.env.MODE);

// basic usage

const isNumber = x => !isNaN(x);
const isPositive = x => x > 0;
const isOdd = x => x % 2 !== 0;
const isSmall = x => x < 123;
const isSmallPositiveOddNumber = x =>
    isNumber(x) && isPositive(x) && isOdd(x) && isSmall(x);

assertType(isSmallPositiveOddNumber, 19);
console.log('19 is a small positive odd number');

try {
    assertType(isSmallPositiveOddNumber, 12);
    console.log('12 is a small positive odd number');
} catch (e) {
    console.log('12 is NOT a small positive odd number:');
    console.log(e.message);
}

// dynamic validation of function arguments and return value
// (in development mode only)

/**
 * Returns the sum of two small positive odd numbers, that
 * should itself be small. Throws if the arguments or the
 * return value do not satisfy type constraints.
 * @param {number} x
 * @param {number} y
 */
const myAdd = (x, y) => {
    assertType(isSmallPositiveOddNumber, x);
    assertType(isSmallPositiveOddNumber, y);
    const sum = x + y;
    assertType(isSmall, sum);
    return sum;
};

console.log('adding 11 and 39:');
console.log(myAdd(11, 39));
try {
    console.log('adding 12 and 99:');
    console.log(myAdd(12, 99));
} catch (e) {
    console.log(e.message);
}
try {
    console.log('adding 55 and 77:');
    console.log(myAdd(55, 77));
} catch (e) {
    console.log(e.message);
}