Confirm the accepted input
A quote accepts a nonnegative finite unit price and a positive whole-number quantity. Text such as "3" is not accepted at this internal calculation boundary. State why conversion belongs before or outside this function if raw text is expected.
function validateQuoteInput(unitPrice, quantity) {
if (!Number.isFinite(unitPrice) || unitPrice < 0) {
return "Price must be a nonnegative finite number";
}
if (!Number.isInteger(quantity) || quantity <= 0) {
return "Quantity must be a positive whole number";
}
return null;
}
console.assert(validateQuoteInput(20, 3) === null);
console.assert(validateQuoteInput(20, "3") !== null);
console.assert(validateQuoteInput(Infinity, 3) !== null);
Number.isFinite rejects NaN, infinities and non-numbers without converting them. Number.isInteger checks integer numeric values. A guard clause handles an invalid or exceptional case early, keeping the normal path readable. This validator returns null for success and a message for failure; use that convention consistently.
Guided design comparison
Deep nesting hides the main calculation under several branches. Guard clauses allow one clear check at a time. However, returning only the first issue is a policy choice. A form may need all issues at once, in which case collect a list instead.
Validation is not just type checking. A negative price is numeric but invalid for this operation. A quantity may also need an upper business limit; add one only after confirming the requirement.
Independent exercise
Add a maximum quantity of 100 to this exercise's confirmed policy. Predict results for 1, 100, 101, 0 and 1.5. Should the validator silently round 1.5?
Correction
1 and 100 are accepted; 101, 0 and 1.5 are rejected. Extend the quantity guard with quantity > 100. Silently rounding changes the requested order; reject with an explanation unless rounding is explicitly agreed.
Review
Decide whether invalid data is rejected, corrected with consent or recorded for review. The implementation should make that decision visible rather than disguising invalid input as a reasonable default.