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
The following function responds with Bad Request HTML when the number of fields in the payload, or their names don’t match the expectation. Also, it examines 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)