-
-
Notifications
You must be signed in to change notification settings - Fork 34.1k
Description
What is the problem this feature will solve?
Validation functions in internal/validators.js are useful, but their utility is limited because the expected type value is hardcoded in their error messages. This prevents their use in scenarios requiring more complex or flexible validation logic.
// lib/internal/validator.js
const validateFunction = hideStackFrames((value, name) => {
if (typeof value !== 'function')
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
});A clear example of this limitation is the necessity for custom, one-off validators in the codebase, such as validateStringArrayOrFunction found in lib/internal/fs/glob.js:
/**
* @callback validateStringArrayOrFunction
* @param {*} value
* @param {string} name
*/
const validateStringArrayOrFunction = hideStackFrames((value, name) => {
if (ArrayIsArray(value)) {
for (let i = 0; i < value.length; ++i) {
if (typeof value[i] !== 'string') {
throw new ERR_INVALID_ARG_TYPE(`${name}[${i}]`, 'string', value[i]);
}
}
return;
}
if (typeof value !== 'function') {
throw new ERR_INVALID_ARG_TYPE(name, ['string[]', 'function'], value);
}
});This function had to be custom-built because the standard validators are not flexible enough to handle a union of types (string[] or function) with a single, reusable utility. It manually implements logic that could ideally be composed from more generic, flexible base validators. This approach leads to code duplication and reduces the overall consistency of validation logic across the project.
What is the feature you are proposing to solve the problem?
I propose enhancing the flexibility of the base validation functions in internal/validators.js by allowing the expected type to be passed as an optional argument. The functions would retain their current behavior by using the existing hardcoded type as a default value.
For example, a generic validateFunction could be modified like this:
const validateFunction = hideStackFrames((value, name, expected = 'Function') => {
if (typeof value !== 'function')
throw new ERR_INVALID_ARG_TYPE(name, expected, value);
});Similarly, we could have a validateStringArray. With more flexible base validators, complex validation logic like that in validateStringArrayOrFunction could be simplified or constructed more cleanly, without needing a completely bespoke implementation for every unique combination of types.
For instance, the check within validateStringArrayOrFunction could be rewritten:
const validateStringArrayOrFunction = hideStackFrames((value, name) => {
if (Array.isArray(value)) {
validateStringArray(value, name);
return;
}
validateFunction(value, name, ['string[]', 'function']);
});What alternatives have you considered?
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status