【问题标题】:TypeScript function that returns arg with extra property (TS2322)返回具有额外属性的 arg 的 TypeScript 函数 (TS2322)
【发布时间】:2021-07-17 02:28:06
【问题描述】:

我想实现一个函数,它接受一个具有一些已知属性和一些未知属性的对象,然后返回一个添加了一些额外属性的对象:

function addY({ x, ...props}) {
  return {
    x,
    y: x + 1,
    ...props,
  };
}

我试过这个:

function addY<T extends { x: number }>({ x, ...props }: T): T & { y: number } {
  return {
    x,
    ...props,
    y: x + 1,
  };
}

我得到的错误是:

TS2322:类型'{ x:数字; } & 省略 & { y: number; }' 不是 可分配给类型 'T & { y: number; }'。键入'{ x:数字; } & 省略 & { y: number; }' 不可分配给类型 'T'。 '{ x:数字; } & 省略 & { y: number; }' 可分配给 'T' 类型的约束,但 'T' 可以用不同的实例 约束的子类型 '{ x: number; }'

我假设如果输入对象有一个与数字不兼容的参数y,那么返回对象将是不可能的。所以我试图通过以下方式减轻它:

function addY<T extends { x: number }>({ x, ...props }: T): Omit<T, "y"> & { y: number } {
  return {
    x,
    ...props,
    y: x + 1,
  };
}

这给出了错误:

TS2322:类型'{ x:数字; } & 省略 & { y: number; }' 不是 可分配给类型 'Omit & { y: number; }'。键入'{ x: 数字; } & 省略 & { y: number; }' 不可分配给类型 '省略'

【问题讨论】:

  • 去掉返回类型,看看TypeScript怎么说
  • @RobertoZvjerković 如果没有返回签名,它仅在y 不在props 中时才有效。如果是,y 的类型将被错误地推断为typeof props.ynumber 的交集。

标签: typescript types typescript-generics


【解决方案1】:

在 TypeScript 中使用扩展语法伪造对象字面量并获取类型可能很棘手。假设x 没有改变,您可以通过不提取x 并将其添加回结果来稍微简化问题,而是单独解构props

function addY<T extends { x: number }>(props: T): Omit<T, 'y'> & { y: number } {
  const {x} = props
  return {
    ...props,
    y: x + 1,
  };
}

这个类型检查,如果你定义了一个函数Normalize来摆脱类型别名

type Normalize<T> = {[K in keyof T]: T[K]}

您可以检查返回类型是否符合预期:

const o1 = addY({x:10, z: 1})
type TestO1 = Normalize<typeof o1> // {x: number, z: number, y: number}

const o2 = addY({x:10, z: 1, y: 'str'})
type TestO2 = Normalize<typeof o2> // {x: number, z: number, y: number}

当然,您也可以使用props.x 代替解构。

TypeScript playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 2021-12-01
    相关资源
    最近更新 更多