【发布时间】:2019-10-31 07:54:50
【问题描述】:
不确定问题是否正确,但我希望它推断结果类型但实际上不知道该怎么做。
我现在是怎么做的:
type StateSetter<S> = (prevState: S) => S;
type ResolvableHookState<S> = S | StateSetter<S>;
export function resolveHookState<S>(state: S): S;
export function resolveHookState<S>(state: StateSetter<S>, currentState?: S): S;
export function resolveHookState<S>(state: ResolvableHookState<S>, currentState?: S): S {
if (typeof state === 'function') {
return (state as StateSetter<S>)(currentState as S);
}
return state;
}
这是我想使用它的方式:
function someFunction(initialState: ResolvableHookState<number> = 0){
const resolvedState = resolveHookState(initialState);
}
想法是让resolveHookState(initialState) 返回数字类型,但由于显而易见的原因它返回ResolvableHookState<number>
我试图通过推断来实现,但它似乎没有像我预期的那样工作。
type ResolvableHookStateType<S extends ResolvableHookState<any>> = S extends StateSetter<infer T> ? T : S;
[UPD 1]
经过一番修修补补后:
export type StateSetter<S> = (prevState?: S) => S;
export type ResolvableHookState<S> = S | StateSetter<S>;
type ResolvableHookStateType<S> = S extends ResolvableHookState<infer T> ? T : never;
export function resolveHookState<S>(state: S): ResolvableHookStateType<S>;
export function resolveHookState<S>(state: StateSetter<S>, currentState?: S): ResolvableHookStateType<S>;
export function resolveHookState<S>(state: ResolvableHookState<S>, currentState?: S): ResolvableHookStateType<S> {
if (typeof state === 'function') {
return (state as StateSetter<S>)(currentState) as ResolvableHookStateType<S>;
}
return state as ResolvableHookStateType<S>;
但我不确定这是解决问题的最优雅的方法。
【问题讨论】:
-
小心
as关键字的使用,它只是告诉TypeScript 闭嘴.. :) 如果我想在我的状态下存储函数会发生什么(这是你第一个忽略的as)?如果我用 stateSetter 调用resolveHookState而没有当前状态(第二个as)怎么办? -
@Grabofus 我正在制作 custorm React 钩子,它应该被用作它的原生
useState,它的参数可以是一个值或返回一个值的函数,如果它是一个调用它的函数没有参数,它的结果用作状态。在这一部分中,它的作用与反应完全一样(如果你想存储一个函数,你必须用另一个函数包装它)。 -
@Grabofus 此外,react 的
useState钩子返回一个可以设置新状态的函数。它也可以是一个值或函数,但这个时间函数将接收 1 个参数 - 当前状态值。因此,如果我是对的(我希望我是 %))我创建了一个涵盖两个用例的函数。这个函数不会暴露给用户,所以有效的用例会被测试捕获 -
唯一的问题是,如果
<S>是函数类型(但不是StateSetter),您将调用它,而不是将其保存为状态。请在下面查看我的答案,看看它是否适合您的情况。 :) -
编辑:删除了答案,似乎有一些问题..如果您没有找到解决方案,我会重新访问并尽快更新
标签: typescript typescript-generics