打字稿:改变函数类型,以便它返回新值打字稿:改变函数类型,以便它返回新值(Typescript: c

2019-05-12 09:14发布

基本上,我想是这样的:

export type ReturnValueMapper<Func extends (...args: Args[] /* impossible */ ) => any, ReturnValue> = (...args: Args[]) => ReturnValue;

我几乎可以肯定,这是不可能的,但我还没有找到确切的证实。


使用情况正在改善类型重新合成的withStateHandlers ,使定义是这样的状态更新程序:

interface StateUpdaters {
    update(field: string): void; // I don't want to specify Partial<State> here 
}

Answer 1:

编辑

由于原来的问题得到回答打字稿提高了可能的解决这个问题。 由于增加了在其他参数和蔓延表达式元组 ,我们现在并不需要具备的所有重载:

type ArgumentTypes<T> = T extends (... args: infer U ) => infer R ? U: never;
type ReplaceReturnType<T, TNewReturn> = (...a: ArgumentTypes<T>) => TNewReturn;

这不仅是短,但它解决了不少问题

  • 可选参数保持可选
  • 参数名被保留
  • 适用于任何数量的参数

样品:

type WithOptional = ReplaceReturnType<(n?: number)=> string, Promise<string>>;
let x!: WithOptional; // Typed as (n?: number) => Promise<string>
x() // Valid
x(1); //Ok

原版的


对于一个好的解决方案,您将需要可变参数的类型 ,但是现在这个答案提供了一个可行的解决方案。 (发布在这里作为类型有用作解决方案的一部分,以不同的问题)。

其基本思想是,我们将提取的参数类型,并用新的返回类型重构函数签名。 有几个缺点,以这种方式:

  1. 参数名称中不保留
  2. 可选参数都处理不好
  3. 仅适用于的参数的具体数量(但更多的可以根据需要增加)

可能还有其他的问题,但根据您的使用情况,直到类型系统解决了这个用例,这可能是一个足够好的解决方案。

type IsValidArg<T> = T extends object ? keyof T extends never ? false : true : true;
type ReplaceReturnType<T, TNewReturn> = T extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E, f: infer F, g: infer G, h: infer H, i: infer I, j: infer J) => infer R ? (
    IsValidArg<J> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => TNewReturn :
    IsValidArg<I> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => TNewReturn :
    IsValidArg<H> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => TNewReturn :
    IsValidArg<G> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => TNewReturn :
    IsValidArg<F> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F) => TNewReturn :
    IsValidArg<E> extends true ? (a: A, b: B, c: C, d: D, e: E) => TNewReturn :
    IsValidArg<D> extends true ? (a: A, b: B, c: C, d: D) => TNewReturn :
    IsValidArg<C> extends true ? (a: A, b: B, c: C) => TNewReturn :
    IsValidArg<B> extends true ? (a: A, b: B) => TNewReturn :
    IsValidArg<A> extends true ? (a: A) => TNewReturn :
    () => TNewReturn
) : never

使用可选参数一起使用时的问题是,可选参数变得需要(并且是type A | undefined ):

type WithOptional = ReplaceReturnType<(n?: number)=> string, Promise<string>>;

let x!: WithOptional;
x(); //invalid
x(undefined);
x(1);


文章来源: Typescript: change function type so that it returns new value