erikdstock
erikdstock

Reputation: 1207

Typescript - Default parameter Type '{}' is not assignable to

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
  )

Upvotes: 1

Views: 552

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249706

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;

Upvotes: 1

Related Questions