Types in plain JavaScript
Typed languages are fine, as far as they go. But unless the type system is Turing complete, type correctness cannot imply program correctness. — Uncle Bob
Let’s explore how we can validate types and precise constraints with convenient error messages in JavaScript. For example:
function updateCardDecimals(cardId, decimals) { isCard(cardId) isValidDecimal(decimals) setCard(cardId, CF.decimals, decimals) }
That function is for formatting UI Drafter’s formulas.

isCard
Let’s ensure that cardId
is a
validly formatted string, and assert the card exists in the collection.
function isCard(cardId) { if (!/^[a-z]+$/i.test(cardId) || !Object.hasOwn(cardsCollection, cardId)) throw new CardNotFound(cardId) } class CardNotFound extends ReferenceError {}
isValidDecimal
In addition to the integer check, we can verify that the value is in the allowed numeric range.
function isValidDecimal(value) { if (!Number.isInteger(value) || value < 0 || value > MAX_FRACTION_DIGITS) throw RangeError(`Invalid Decimal "${value}"`) }
BTW, the JavaScript Error Types:
EvalError
,
RangeError
,
ReferenceError
,
SyntaxError
,
TypeError
,
URIError
,
AggregateError
Server Side Example
In the following function we’ll send a Bad Request HTML response when the number of fields in the payload, or their names, don’t match the expectation. Also, we’ll examine the values beyond their data type.
const AuthError = 1 const ValidationError = 2 async function resetPasswordPost(request, response) { try { const body = await jsonBody(request) if (!( body && Object.keys(body).length === 3 && isPassword(body.password) && isId(body.userId) && isId(body.token) )) throw ValidationError if (!await passwordResetTokenExists(body.token, body.userId)) throw AuthError // … sendOk(response) } catch (error) { switch (error) { case AuthError: sendUnauthorized(response); break; case ValidationError: sendBadRequest(response); break; default: sendInternalServerError(response); } } }
function isId(value) { return check(value, String) && value.length === StandardIdCharLength && /^[\w-]*$/.test(value) }
Open Source
Check out this library: type-check
check('a', String) check(100, Number) check(new Int8Array([1, 2, 3]), Int8Array)