UI Drafter

JavaScript
Types without TypeScript

by Eric Fortis

1. Traditional Data Types

Check out this library: type-check

check('a', String)
check(100, Number)
check(new Int8Array([1, 2, 3]), Int8Array)

2. More than Type Checks

In addition to the data type, let's validate with more precise constraints and convenient messages. For example:

function updateCardDecimals(cardId, decimals) {
  isCard(cardId)
  isValidDecimal(decimals)
  setCard(cardId, CF.decimals, decimals)
}

For context, the function sets the decimals of the card total.

Update Decimals of the Formula Total

isCard

This function ensures cardId is a validly formatted string. Also, it asserts the card in the collection.

function isCard(cardId) {
  if (!/^[a-z]+$/i.test(cardId) || !Object.hasOwn(_cards, cardId))
    throw new CardNotFound(cardId)
}

class CardNotFound extends ReferenceError {}

isValidDecimal

In addition to the integer check, it verifies the numeric range.

function isValidDecimal(value) {
  if (!Number.isInteger(value)
     || value < 0
     || value > MAX_FRACTION_DIGITS)
      throw RangeError(`Invalid Decimal "${value}"`)
}

JavaScript Error Types

EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, AggregateError

3. Another Example

This function counts the number of entries in the payload and validates their names and values.

const AuthError = 1
const ValidationError = 2

const isId = value =>
  isString(value)
    && value.length === StandardIdCharLength
    && /^[\w-]*$/.test(value)

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 isString(value) {
  return isTypeOf('')(value)
}

function isTypeOf(example) {
  const egType = Object.prototype.toString.call(example)
  return val => Object.prototype.toString.call(val) === egType
}

Sponsored by: