基本上,我想是这样的:
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
}
编辑
由于原来的问题得到回答打字稿提高了可能的解决这个问题。 由于增加了在其他参数和蔓延表达式元组 ,我们现在并不需要具备的所有重载:
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
原版的
对于一个好的解决方案,您将需要可变参数的类型 ,但是现在这个答案提供了一个可行的解决方案。 (发布在这里作为类型有用作解决方案的一部分,以不同的问题)。
其基本思想是,我们将提取的参数类型,并用新的返回类型重构函数签名。 有几个缺点,以这种方式:
- 参数名称中不保留
- 可选参数都处理不好
- 仅适用于的参数的具体数量(但更多的可以根据需要增加)
可能还有其他的问题,但根据您的使用情况,直到类型系统解决了这个用例,这可能是一个足够好的解决方案。
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);