使用多个泛型回调对函数中的参数重新排序时,泛型类型推断失败

问题描述 投票:0回答:1

我正在 TypeScript 中实现一个类型安全的

shapeAdapter
函数,它接受一个原始对象、一个用于转换它的
adapt
函数以及一个用于将其转换回来的
revert
函数。

function shapeAdapter<Original, Transformed>(props: {
  original: Original;
  adapt: (original: NoInfer<Original>) => Transformed;
  revert: (transformed: NoInfer<Transformed>) => NoInfer<Original>;
}) {
  throw new Error("Implementation does not matter")
}

adapt
revert
之前声明时,该函数将按预期工作:

shapeAdapter({
  original: { value: 1 },
  adapt: (original) => original.value,
  revert: (transformed) => ({ value: transformed }), // transformed is of type number as expected
})

但是,当我交换

adapt
revert
的顺序时,类型推断就会中断:

shapeAdapter({
  original: { value: 1 },
  revert: (transformed) => ({ value: transformed }), // "transformed" is of type unknown! should be number
  adapt: (original) => original.value,
})

在第二个示例中,

transformed
函数中的
revert
被推断为
unknown
而不是
number

我使用

NoInfer
实用程序类型来防止过度类型加宽,但它不能解决此问题。

有没有办法无论这些回调的顺序如何都保持正确的类型推断?

TypeScript 版本:

5.5.2

游乐场链接 TS 游乐场

我尝试过的: 我最初在

adapt
之前使用
revert
实现了该函数,它按预期工作,但后来我尝试重新排序参数,将
revert
放在
adapt
之前,但它破坏了类型推断,然后我尝试使用
NoInfer
通用参数上的实用程序类型可以防止过度类型扩展,但这也没有帮助。

我的期望: 我希望 TypeScript 能够根据

Original
函数的结构推断
Transformed
shapeAdapter
类型之间的关系,而不管回调的顺序如何。

typescript
1个回答
0
投票

请尝试改变

revert: (transformed: NoInfer<Transformed>) => NoInfer<Original>;

revert: (transformed: NoInfer<Transformed>) => Original;

有效的代码中发生了什么

shapeAdapter({
  original: { value: 1 }, // Original is inferred as { value: number }
  adapt: (original) => original.value, // Transformed is inferred as number
  revert: (transformed) => ({ value: transformed }) // return value is inferred as Original
});

不起作用的代码中发生了什么

shapeAdapter({
  original: { value: 1 }, // OK, as above
  revert: (transformed) => ({ value: transformed }), // fails because of NoInfer on both Original and Transformed 
  adapt: (original) => original.value
})
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.