Reputation: 1207
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 (noas any
).Cannot find name 'E'
if I preface= {}
with the:E
typeType expected
if I useas 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
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