Typescript 创建包装其他函数的函数的泛型类型

Typescript 创建包装其他函数的函数的泛型类型,typescript,Typescript,如何为函数createWrapper编写泛型类型,以使示例末尾的返回类型与指定的返回类型一致 function createWrapper(wrapper) { return fn => wrapper(fn); } const wrap = createWrapper(fn => { if (Math.random() < 0.5) { return 4 as const; } const result = fn(); return result

如何为函数createWrapper编写泛型类型,以使示例末尾的返回类型与指定的返回类型一致

function createWrapper(wrapper) {
  return fn => wrapper(fn);
}

const wrap = createWrapper(fn => {
  if (Math.random() < 0.5) {
    return 4 as const;
  }
  const result = fn();
  return result === 0 ? null : result;
});

const nullOrOneOrFour = wrap(() => {
  return Math.random() < 0.5 ? (0 as const) : (1 as const);
});

const twoOrThreeOrFour = wrap(() => {
  return Math.random() < 0.5 ? (2 as const) : (3 as const);
});

// ReturnType<typeof nullOrOneOrFour> -> null | 1 | 4
// ReturnType<typeof nullOrTwoOrThreeOrFour> -> null | 2 | 3 | 4
函数createWrapper的定义是唯一应该有显式类型注释的区域。理想情况下,其他一切都可以推断出来


在进一步研究这个问题之后,我想我可能需要像高阶类型这样的东西来正确地实现这一点,即泛型。这条评论似乎与我试图实现的目标有关:。

下面是函数返回类型的简单示例

greet() : number {
    return n;
}

我已经检查并添加了所有类型,直到可以推断出其他类型。 您可能可以选择不同的内容来添加类型,以正确推断结果

键入的代码 函数createWrapperwrapper:fn:=>Output=>FinalOutput:fn:=>Output=>FinalOutput{ 返回fn=>wrapperfn; } 常量换行:fn:=>Output=>Output | 4 | 0扩展输出?null:never=createWrapperfn=>{ 如果Math.random<0.5{ 返回4作为常量; } 常数结果=fn; 返回结果为未知===0?空:结果为任意; }; 常量nullOrOneOrFour=wrap=>{ 返回Math.random<0.5?0作为常量:1作为常量; }; 常数twoOrThreeOrFour=换行=>{ 返回Math.random<0.5?2作为常量:3作为常量; }; nullOrOneOrFour被推断为null | 1 | 4, 和 两个或四个被推断为2 | 3 | 4

createWrapper 接受一个函数,该函数接受单个函数并返回一些值, 并返回一个函数,该函数接受一个函数并返回该值

老实说,我不太确定它的用途,因为它对只接受一个参数的函数没有任何作用。也许你有一些我想不起来的用例,但不管怎样,它都是打字系统的一个很好的例子

包 接受一个输出某物的函数,并输出该某物,4,如果该某物为0,则为null

不幸的是,我不得不添加一个as unknown来生成这个函数,因为很明显,在typescript中,您无法将任意类型与0进行比较。我不认为这有什么意义,但它是


此外,我还必须将as any添加到最终返回中,因为我无法将其转换为type,因此只有在0扩展输出时才可以使用null。它使该函数的类型化变得丑陋,但使其任何调用者中的类型推断都很好。如果另一个答案可以去掉as any,但在最后两个常量上仍然得到正确的类型推断,那么他们的答案可能比我的好。

对不起,createWrapper的代码是什么。这不是你想要的吗type@jstuartmilne我在您提到的注释中添加了CreateWrapper的代码nullOrTwoOrThreeOrFour,但在代码中有两个或四个。评论应该是说两个或四个吗?我在问题中添加了一些额外的上下文以使问题更清楚。createWrapper是唯一应该有显式类型注释的函数。@Braden这可能有点乐观。无法正确推断以下函数的返回类型:函数replaceNullWithZerot:T{return T==0?null:T;}由于wrap中有类似的内容,因此无论您使用createWrapper做什么,它都无法正确推断。甚至无法接近所问问题的复杂性