首页 > 解决方案 > 打字稿 - 默认参数类型“{}”不可分配给

问题描述

我已经为一个表单编写了一个简单的验证方法,它接受一个{ [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
  )

标签: typescript

解决方案


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;

推荐阅读