繁体   English   中英

为什么 TypeScript 不能推断出这个 function 的返回类型?

[英]Why can't TypeScript infer the return type of this function?

我正在尝试编写一些克隆对象但更改深层属性的实用程序函数。

这是一个有点无用的版本的示例,它只是将 object 的命名属性替换为其他可能属于不同类型的值。 该代码有效 - 它用新值替换了命名属性 - 但由于某种原因 TypeScript 无法确定创建的 object 的类型并给出编译错误。 为什么 TypeScript 不像这样,我怎样才能让它工作?

我可以显式地定义返回类型——但是对于这个 function 的版本来说,这会变得很尴尬,因为它改变了几个级别的属性。

it('change type of input object', () => {
  const cloneWith = <T extends Record<string, unknown>, A extends keyof T, V>(
    i: T,
    a: A,
    value: V
  ) => ({
    ...i,
    [a]: value,
  });
  const source = { name: 'bob', age: 90 };
  const result = cloneWith(source, 'age', 'old!');

  // This test passes
  expect(result.age).to.equal('old!');

  // But compile error - number and string have no overlap -
  // on this line
  if (result.age === 'old!') {
    console.log('That person is old!');
  }
});

使用扩展语法创建的 object 文字的推断类型并不总是理想的,尤其是在涉及计算属性时。 在这种情况下, T与索引签名{[x: string]: V}相交,而Omit<T, A> & {[K in A]: V}会更有意义(没有属性AT和带有键A和值T的单独 object )。

如果没有明确的返回类型,我看不出如何解决这个问题,但是如果添加返回类型,至少会推断出正确的类型。 也许您可以为 function 的其他版本做类似的事情。

const cloneWith = <T, A extends keyof T, V>(
  i: T,
  a: A,
  value: V
): Omit<T, A> & {[K in A]: V} => ({
  ...i,
  [a]: value,
});

const source = { name: 'bob', age: 90 };
const result = cloneWith(source, 'age', 'old!');
type TestSource = typeof source.age // number
type TestResult = typeof result.age // string

TypeScript操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM