Skip to content

Instantly share code, notes, and snippets.

@markheramis
Created November 14, 2024 03:26
Show Gist options
  • Select an option

  • Save markheramis/eeeed0ae4430c77279760e14d36b5589 to your computer and use it in GitHub Desktop.

Select an option

Save markheramis/eeeed0ae4430c77279760e14d36b5589 to your computer and use it in GitHub Desktop.
This project is a demonstration of how to cleanly validate function parameters in typescript without 3rd party dependencies.

Clean Parameter Validation in TypeScript

This project demonstrates a clean, reusable approach to validating function parameters in TypeScript. It includes a sample UserData interface, a validateUserData function for runtime validation, and a createUser function that uses the validated parameters.

Purpose

This code snippet showcases how to enforce strict validation of function parameters in TypeScript by:

Defining an interface to outline the expected structure. Using a separate validation function to check the parameter's conformance before it’s passed to the main function.

Overview

Code Components

UserData Interface: Specifies the expected shape of an object with username and email as required string properties. validateUserData Function: Separates the validation logic, allowing for clean parameter validation outside of the main function. createUser Function: Accepts a validated UserData object and performs further actions, demonstrating how to handle strictly validated data.

Usage

Validation Function: Use validateUserData(data) to verify that an object matches the UserData type. Main Function: After validation, pass the data to createUser.

// Define the structure of the allowed data
interface UserData {
username: string;
email: string;
}
// Separate validation function to check if input is a valid UserData object
const validateUserData = (data: unknown): UserData => {
// Check if data is an object
if (typeof data !== "object" || data === null) {
throw new Error("Input data must be a non-null object.");
}
// Check for required properties and their types
if (
typeof (data as UserData).username !== "string" ||
typeof (data as UserData).email !== "string"
) {
throw new Error("The object must contain 'username' and 'email' as strings.");
}
// Ensure no extra properties are present
const allowedKeys = ["username", "email"];
const dataKeys = Object.keys(data);
if (dataKeys.some((key) => !allowedKeys.includes(key))) {
throw new Error("The object must contain only 'username' and 'email' properties.");
}
// Return data as UserData if validation passes
return data as UserData;
};
// Main function that expects a validated UserData object
const createUser = async (data: UserData) => {
// Proceed with function logic, assuming data is correctly structured
console.log("Valid data:", data);
};
// Example usage
try {
// Attempt to pass an invalid object (this will throw an error)
const invalidData = { username: "example", password: "example" }; // Incorrect property "password"
const validatedInvalidData = validateUserData(invalidData); // Will throw an error
createUser(validatedInvalidData); // This line won't be reached
} catch (error) {
console.error("Validation error:", error); // Logs: "The object must contain only 'username' and 'email' properties."
}
try {
// Attempt to pass a valid UserData object
const validData = { username: "exampleUser", email: "[email protected]" };
const validatedData = validateUserData(validData); // Passes validation
createUser(validatedData); // Logs: "Valid data: { username: 'exampleUser', email: '[email protected]' }"
} catch (error) {
console.error("Validation error:", error);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment