DEV Community

Alan Buenrostro
Alan Buenrostro

Posted on

πŸ› οΈ Simple Shallow Type Checker in JavaScript

JavaScript's dynamic typing is both a blessing and a curse. Sometimes you just want a lightweight way to validate the shape and types of an object β€” without pulling in a full schema validator or TypeScript.

Here's a simple utility function for shallow type checking using plain JavaScript:


πŸ“¦ The Code

/**
 * @typedef {Object} TypeDefinitionItem
 * @property {string} keyName - The name of the key to check on the object.
 * @property {string} type - The expected JavaScript type of the value (e.g. "string", "number", "boolean").
 */

/**
 * @typedef {TypeDefinitionItem[]} TypeDefinition
 */

/**
 * @description A shallow type checker. Verifies that an object's key-value pairs match the expected type definitions.
 * @param {TypeDefinition} typeDefinition - An array of type definition items specifying keys and expected types.
 * @param {Object} objectToCheck - The object to validate against the type definitions.
 * @returns {boolean} Returns true if all keys exist and have the correct type, otherwise false.
 */
export function shallowTypeCheck(typeDefinition, objectToCheck) {
    try {
        for (let property of typeDefinition) {
            // Check if key exists in the object
            const keyExists = objectToCheck.hasOwnProperty(property.keyName);
            if (keyExists) {
                const typeCorrect = typeof objectToCheck[property.keyName] === property.type;
                if (!typeCorrect) {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    } catch (e) {
        return false;
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Example Usage

const typeDef = [
  { keyName: 'name', type: 'string' },
  { keyName: 'age', type: 'number' },
  { keyName: 'isAdmin', type: 'boolean' }
];

const user = {
  name: 'Alice',
  age: 30,
  isAdmin: false
};

console.log(shallowTypeCheck(typeDef, user)); // true
Enter fullscreen mode Exit fullscreen mode

πŸ”΄ What if the types don't match?

const invalidUser = {
  name: 'Bob',
  age: 'thirty', // ❌ should be a number
  isAdmin: false
};

console.log(shallowTypeCheck(typeDef, invalidUser)); // false
Enter fullscreen mode Exit fullscreen mode

🚫 Limitations

  • It's shallow: it doesn't check nested objects.
  • It doesn't support complex types like arrays, classes, or custom validators.
  • For more robust validation, consider libraries like zod, yup, or io-ts.

βœ… When to Use This

This is useful when:

  • You want lightweight validation with no dependencies.
  • You’re working in a Node.js project without TypeScript.
  • You need quick runtime guards for input objects.

Top comments (2)

Collapse
 
cookiemonsterdev profile image
Mykhailo Toporkov πŸ‡ΊπŸ‡¦ • Edited

Can be improved like:

const DataType = Object.freeze({
  String: "string",
  Number: "number",
  Boolean: "boolean",
  Undefined: "undefined",
  Null: "null",
  Object: "object",
  Array: "array",
  Function: "function",
  Symbol: "symbol",
  BigInt: "bigint",
});

export function shallowTypeCheck(typeDefinition, objectToCheck) {
  for (const key in typeDefinition) {
    const expectedType = typeDefinition[key];
    const actualValue = objectToCheck[key];

    let actualType;

    actualType = typeof actualValue;

    switch (true) {
      case actualValue === null: {
        actualType = DataType.Null;
        break;
      }
      case Array.isArray(actualValue): {
        actualType = DataType.Array;
        break;
      }
      default: {
        actualType = typeof actualValue;
      }
    }

    if (actualType !== expectedType) return false;
  }

  return true;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
alanlovesw3 profile image
Alan Buenrostro

Thanks! I love how you handled the iteration using object.Freeze!