-
Notifications
You must be signed in to change notification settings - Fork 34
Closed
Description
The length check for a Parameter list tuple is too strict in the case of optional parameters (or in fact any array where the final element(s) can validly be undefined).
Here's a case to reproduce the issue:
import * as assert from 'assert';
import { createIs } from '../index';
describe('is', () => {
function foo(_a: number, _b?: string) { return; }
type FooParams = Parameters<typeof foo>;
const isFooParams = createIs<FooParams>();
describe('isFooParams', () => {
it('should return true for valid parameters, optional or not', () => {
assert.deepStrictEqual(isFooParams([1, 'a']), true);
assert.deepStrictEqual(isFooParams([1]), true);
assert.deepStrictEqual(isFooParams([1, undefined]), true);
assert.deepStrictEqual(isFooParams([1, null]), false);
});
});
});
The second assert (incorrectly) fails: element [1] of the array is indeed undefined.
In the generated output (below) there is an inappropriate test for Array.length===2.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const index_1 = require("../index");
describe('is', () => {
function foo(_a, _b) { return; }
const isFooParams = index_1.createIs(object => {
var path = ["$"];
function _number(object) {
if (typeof object !== "number")
return "validation failed at " + path.join(".") + ": expected a number";
else
return null;
}
function _undefined(object) {
if (object !== undefined)
return "validation failed at " + path.join(".") + ": expected undefined";
else
return null;
}
function _string(object) {
if (typeof object !== "string")
return "validation failed at " + path.join(".") + ": expected a string";
else
return null;
}
function su__undefined__string_eu(object) {
var conditions = [_undefined, _string]; for (const condition of conditions) {
var error = condition(object);
if (!error)
return null;
} return "validation failed at " + path.join(".") + ": there are no valid alternatives";
}
function st__number_su__undefined__string_eu_et_9_396(object) {
/* HERE: array.length might be <= 2 since all the final elements after length=1 can validly be undefined */
if (!Array.isArray(object) || object.length !== 2)
return "validation failed at " + path.join(".") + ": expected an array of length 2"; {
path.push("[0]");
var error = _number(object[0]);
path.pop();
if (error)
return error;
} {
path.push("[1]");
var error = su__undefined__string_eu(object[1]);
path.pop();
if (error)
return error;
} return null;
} var error = st__number_su__undefined__string_eu_et_9_396(object); return error;
});
describe('isFooParams', () => {
it('should return true for valid parameters, optional or not', () => {
assert.deepStrictEqual(isFooParams([1, 'a']), true);
assert.deepStrictEqual(isFooParams([1]), true);
assert.deepStrictEqual(isFooParams([1, undefined]), true);
assert.deepStrictEqual(isFooParams([1, null]), false);
});
});
});
Output
Metadata
Metadata
Assignees
Labels
No labels