我已经为表单编写了一种简单的验证方法,该表单接受{ [name: string]: string }
中的值对象,并返回部分相同类型的错误消息,但有关我的类型的某些信息不起作用-第三种除非我将E
键入的自变量错误,除非我用以下任一方式将其命名为any
:
Type '{}' is not assignable to type 'E'
。如果我没有提供类型信息(没有as any
)。Cannot find name 'E'
,如果我以= {}
类型开头:E
Type expected
(如果我使用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
)
答案 0 :(得分:1)
Typescript不允许您将对象文字分配给通用类型的变量。虽然泛型类型约束为该类型指定了最低限度的合同,但是可以想象,该类型可能包含所需的属性(例如T
以外的属性)。这意味着由于Typescript无法证明该值对任何E
都是有效的,因此它不会让您进行赋值。
在您的情况下,最简单的解决方案是拥有一个公共的通用签名和一个更简单的非通用实现签名。
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;