Limit the object's values to only singular, non-array data points

I'm currently working with Formik, which includes this particular type:

type FormikErrors<Values> = {
 [K in keyof Values]?: Values[K] extends object
  ? FormikErrors<Values[K]>
  : string
};

In addition to this type, there is a validation function that resembles

validate<Values>(v: Values) => FormikErrors<Values>
. The main concept here is that the keys of FormikErrors align with the keys of Values and correspond to either a string error message or a recursive FormikErrors object if the field is represented by a nested object.

My objective is to create a generic function for validating required fields. This function specifically targets flat Values.

export function validateRequired<T, K extends keyof T>(values : T, names: K[]) : FormikErrors<T> {
 let errors : FormikErrors<T> = {};
 names.forEach((name) => {
  if (!values[name]) {
   errors[name] = 'This field is required';
  }
 });
 return errors;
}

An issue arises with this setup:

Type error: Type '"This field is required"' is not assignable to type '(T[K] extends object ? FormikErrors<T[K]> : string) | undefined'. TS2322

This error occurs because the values returned by validateRequired are always strings and never nested FormikValues. Is there a method to indicate that the values will consistently be scalars so that this can pass the type checking?

Answer №1

To avoid using the FormikErrors type, consider utilizing a custom type that is limited to string values:

type RequiredErrors<Values> = {
    [K in keyof Values]?: string
};

export function validateRequired<T, K extends keyof T>(values: T, names: K[]): RequiredErrors<T> {
    let errors: RequiredErrors<T> = {};
    names.forEach((name) => {
        if (!values[name]) {
            errors[name] = 'This field is required';
        }
    });
    return errors;
}

If using a custom type is not feasible, resorting to a type assertion may be necessary. Since TypeScript struggles with conditional types containing unresolved generic parameters, it needs guidance on whether 'string' is an acceptable value for the 'errors' object. A type assertion can resolve this issue:

export function validateRequired<T, K extends keyof T>(values: T, names: K[]): FormikErrors<T> {
    let errors: FormikErrors<T> = {};
    names.forEach((name) => {
        if (!values[name]) {
            errors[name] = 'This field is required' as any;;
        }
    });
    return errors;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JSONPath encounters an issue when square brackets are embedded within a string

I am encountering issues with the JSONPath library found at https://github.com/JSONPath-Plus/JSONPath in its latest version. For example: { "firstName": "John", "lastName": "doe", "age": 26, ...

unable to send a response back with nextApiResponse

I've been attempting to submit a response in Next.js, but I keep encountering this error on Vercel: Error message: inside catch 1 TypeError: t.status is not a function Here's the code snippet causing the issue: export async function GET(req: N ...

Metronome in TypeScript

I am currently working on developing a metronome using Typescript within the Angular 2 framework. Many thanks to @Nitzan-Tomer for assisting me with the foundational concepts, as discussed in this Stack Overflow post: Typescript Loop with Delay. My curren ...

Unexpected actions in the while loop within the workplace script

This code snippet I have been using to update cell A1 doesn't seem to be working: function main(workbook: ExcelScript.Workbook) { let worksheet = workbook.getWorksheet("Sheet1"); var i: number = 0; while (true) { worksheet.getR ...

Tips for adjusting the search bar's position on a mobile device when it is activated by the user

I need help with an open source project where I am developing a search engine using Angular. When using smaller screen sizes, the search bar is positioned in the middle but gets hidden behind the keyboard terminal when clicked on. Can anyone advise on ho ...

The limitations of Typescript types influence the program's behavior

As a newcomer to the Typescript environment, I am currently developing a test application to familiarize myself with it. However, I have encountered an issue regarding type restrictions that seems to be not working as expected. In my class, I have defined ...

Issue with Bazel and Angular Production Server: "Encountering Uncaught SyntaxError: Unexpected token '<'"

Utilizing this sample application found in the rules_nodejs repository, I've created an Angular app template that can be constructed or served using Bazel. The ts_devserver (BUILD file) launches without issues. However, there is a problem when servin ...

Validate a string to determine if it is a legitimate numerical value using Javascript

How can we accurately determine if a string is a valid number in JavaScript? Although the method isNaN(str) is commonly used, it has limitations in certain cases, Current behavior: isNaN("1") = false, as it is a number, isNaN("1 ") = ...

Guide to setting data types for [key, value] pairs within a forEach iteration

I am currently encountering a typescript syntax error in my project that is indicating the need to define the prodStatus variable... const products = { 1: {isUpdating: false, qty: 2}, 2: {isUpdating: true, qty: 4} } const updatingProducts: Array< ...

Unable to initiate ngModelChange event during deep cloning of value

I've been struggling to calculate the sum of row values, with no success. My suspicion is that the issue lies in how I am deep cloning the row values array when creating the row. const gblRowVal1 = new GridRowValues(1, this.color, this.headList ...

How can users create on-click buttons to activate zoom in and zoom out features in a Plotly chart?

I am currently working on an Angular application where I need to implement zoom in and zoom out functionality for a Plotly chart. While the default hoverable mode bar provides this feature, it is not suitable for our specific use case. We require user-cr ...

Is there a way to mark a template-driven form as invalid when a custom field validator fails in my Angular 15 application?

Currently, I am working on an Angular 15 app that utilizes a hand-coded JSON file along with the JSON server for performing CRUD operations on a "employees" JSON data. One of the tasks at hand involves adding custom validation to a <select> element. ...

Typescript error: The value "X" cannot be assigned to this type, as the properties of "Y" are not compatible

Disclaimer: I am relatively new to Angular2 and typescript, so please bear with me for any errors. The Challenge: My current task involves subtracting a start date/time from an end date/time, using the result in a formula for my calculation displayed as " ...

What is the best way to retrieve the name of a static method within a class?

In my code, I am logging multiple messages in a static method and I want to use the method name as context. However, I do not want to create a separate variable called `context` and assign the function/method name to it. I would like to be able to access ...

Struggling to display data from Firebase Database in dropdown menu using Angular

Despite my extensive search efforts online, including watching YouTube videos and enrolling in Udemy courses, I have not been able to find the solution to my issue. My goal is to take an observable retrieved from Firebase and populate it into a dropdown me ...

Submitting a File to a Server using Ionic

I am trying to upload a JSON/CSV file to the server and store it in a specific location similar to how I manually upload files using FileZilla. The goal is to be able to retrieve this file later on from a different user. I attempted to use the http.post m ...

Tips for setting or patching multiple values in an ngselect within a reactive form

https://i.sstatic.net/ct6oJ.png I am facing an issue with my ng select feature that allows users to select multiple languages. However, upon binding multiple selected values in the ng select, empty tags are being displayed. I have included my code below. * ...

How is it possible for Typescript to let me create an object without explicitly defining all mandatory fields?

After creating a class and instantiating an object from it through the constructor, I expected to receive an error message indicating missing properties. However, despite the fact that the class description specified required fields, I was able to create a ...

After compiling typescript, ES6 Map.forEach is unexpectedly not a function

Exploring the new collection types introduced in ES6 for my TypeScript/React project. interface MyComponentProps{ myMap: Map<String, {isAvailable?: boolean}>, } ... this.props.myMap.keys(); Even though IntelliJ and Webpack compile the code withou ...

What is the procedure for transferring the inputted data from an HTML file to its corresponding TS file and subsequently to a different component file?

I have created two components, a login and a home-page. I am attempting to capture user input from the login template, pass it to the login component, and then display it on the home-page template using the home-page component. What is the best approach to ...