1

I've written a simple validation method for a form that takes a { [name: string]: string } object of values in and returns a partial of the same type with error messages, but something about my types isn't working- the Third E typed argument is erroring unless I call it any with either:

  • Type '{}' is not assignable to type 'E'. if I give no type information (no as any).
  • Cannot find name 'E' if I preface = {} with the :E type
  • Type expected if I use as E
export const requiredFields: <
  T extends { [propName: string]: string },
  K extends keyof T,
  E extends Partial<T>
>(
  fields: K[],
  values: T,
  startingErrors?: E
) => E = (fields, values, startingErrors: E = {}) =>
  reduce(
    fields,
    (acc, fieldName) =>
      values[fieldName].length
        ? acc
        : Object.assign({}, acc, { [fieldName]: "Required" }),
    startingErrors
  )

1 Answer 1

1

Typescript will not let you assign object literals to a variable of a generic type. While the generic type constraint specifies a minimum contract for the type, the type could conceivably contain required properties (other than those of T) for example. This means that since Typescript can't prove the value is valid for any E it will not let you do the assignment.

In your case the simplest solution is to have a public generic signature and a simpler non generic implementation signature.

export function requiredFields <
  T extends { [propName: string]: string },
  K extends keyof T,
  E extends Partial<T>
>(
  fields: K[],
  values: T,
  startingErrors?: E
):E
export function requiredFields(fields: string[], values: Record<string, string>, startingErrors: Record<string, string> = {}) :Record<string, string> {
  return reduce(
    fields,
    (acc, fieldName) =>
      values[fieldName].length
        ? acc
        : Object.assign({}, acc, { [fieldName]: "Required" }),
    startingErrors
  )
}

declare function reduce<T, U>(arr: T[], a: (acc: U, e: T) => U, i: U): U;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.