Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup

In a recent project, I encountered a problem where we needed to validate an object with keys dynamically defined by a constant map and enforce that at least one key has a valid value.

The Challenge

We had a MetadataMap object that defined valid keys…


This content originally appeared on DEV Community and was authored by Saurabh Saha

In a recent project, I encountered a problem where we needed to validate an object with keys dynamically defined by a constant map and enforce that at least one key has a valid value.

The Challenge

We had a MetadataMap object that defined valid keys and their corresponding types:

const MetadataMap = {
userId: Number,
utmSource: String,
utmMedium: String,
utmCampaign: String,
} as const;

From this map, we needed to:

  1. Dynamically generate a TypeScript interface to enforce type safety.
  2. Create a Yup validation schema that validates the object based on the map.
  3. Ensure at least one key in the object has a valid, non-undefined value.
  4. Avoid hardcoding keys to make the solution maintainable.

But, TypeScript enforces static types at compile time, while Yup handles runtime validation.

Step 1: Generating the Interface
To generate the TypeScript interface from the MetadataMap, we used keyof and mapped types. Here’s how we defined it:

type Metadata = {
[K in keyof typeof MetadataMap]: typeof MetadataMap[K] extends NumberConstructor
? number
: string;
};

This approach ensured that any updates to MetadataMap were automatically reflected in the Metadata interface. For example:

// Resulting Metadata interface:
interface Metadata {
userId?: number;
utmSource?: string;
utmMedium?: string;
utmCampaign?: string;
}

Step 2: Dynamically Generating the Yup Schema

We needed to dynamically create a Yup schema that matched the keys and types in MetadataMap. Using Object.keys and a reducer, we mapped each key to its corresponding Yup validator:

const metadataSchema = Yup.object(
Object.keys(MetadataMap).reduce((schema, key) => {
const type = MetadataMap[key as keyof typeof MetadataMap];
if (type === Number) {
schema[key] = Yup.number().optional();
} else if (type === String) {
schema[key] = Yup.string().optional();
}
return schema;
}, {} as Record<string, any>)
);

This method eliminated hardcoding and ensured that changes in MetadataMap were reflected in the schema without manual updates.

Step 3: Adding the “At Least One Key” Rule

The next challenge was ensuring that at least one key in the object had a defined value. We added a .test method to the Yup schema:

metadataSchema.test(
"at-least-one-key",
"Metadata must have at least one valid key.",
(value) => {
if (!value || typeof value !== "object") return false;
const validKeys = Object.keys(MetadataMap) as (keyof typeof MetadataMap)[];
return validKeys.some((key) => key in value && value[key] !== undefined);
}
);

This logic:

  1. Ensures the object is valid.
  2. Extracts valid keys dynamically from MetadataMap.
  3. Verifies that at least one key has a non-undefined value.

The Result
Here’s how the final schema behaves:

const exampleMetadata = {
userId: undefined,
utmSource: "google",
extraField: "invalid", // This key is ignored.
};

metadataSchema
.validate(exampleMetadata)
.then(() => console.log("Validation succeeded"))
.catch((err) => console.error("Validation failed:", err.errors));

In this example, validation succeeds because utmSource is a valid key with a non-undefined value, even though userId is undefined and extraField is not part of MetadataMap.


This content originally appeared on DEV Community and was authored by Saurabh Saha


Print Share Comment Cite Upload Translate Updates
APA

Saurabh Saha | Sciencx (2025-01-24T08:03:26+00:00) Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup. Retrieved from https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/

MLA
" » Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup." Saurabh Saha | Sciencx - Friday January 24, 2025, https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/
HARVARD
Saurabh Saha | Sciencx Friday January 24, 2025 » Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup., viewed ,<https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/>
VANCOUVER
Saurabh Saha | Sciencx - » Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/
CHICAGO
" » Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup." Saurabh Saha | Sciencx - Accessed . https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/
IEEE
" » Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup." Saurabh Saha | Sciencx [Online]. Available: https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/. [Accessed: ]
rf:citation
» Dynamically Generating Interfaces and Validation Schemas in TypeScript with Yup | Saurabh Saha | Sciencx | https://www.scien.cx/2025/01/24/dynamically-generating-interfaces-and-validation-schemas-in-typescript-with-yup/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.