我正在尝试编写与此非常相似的代码:
const globalState = {
searchState: {
id: "value"
}
};
interface MapState<Result> {
(state: any): Result;
}
interface SearchState {
id: string;
}
interface HasSearchState {
searchState: SearchState;
}
const createUseMapState = <State>() => {
return (mapState: MapState<State>) => mapState(globalState);
};
const useHasSearchState = createUseMapState<HasSearchState>();
const useSearchState = (mapState?: <T>(state: SearchState) => T) => {
if (mapState) {
return useHasSearchState((hasState) => mapState(hasState.searchState));
}
return useHasSearchState((hasState) => hasState.searchState);
};
const useId = () => useSearchState((state) => state.id); // <-- Error here!
在CodePen中可用。
TypeScript(3.3.3)在最后一行给出TS2345:
Argument of type '<T>(state: SearchState) => string' is not assignable to parameter of type '<T>(state: SearchState) => T'.
Type 'string' is not assignable to type 'T'.
如果我将最后一个功能更改为不使用中间功能,则可以使用:
const useId = () => useHasSearchState((state) => state.searchState.id);
如何声明useSearchState
函数的类型,以便在useId
类型检查中使用它?
在React库的帮助下,使用Hooks的redux-hooks是真实代码的上下文。
我觉得应该正确输入check,但是显然我误会了一些东西。
答案 0 :(得分:1)
将T参数提升到外部函数。
const a = (m: <T>() => T) => {
return m();
}
// Type 'string' is not assignable to type 'T'
a(() => 'Hey!');
但是
const a = <T>(m: () => T) => {
return m();
}
// Ok!
a(() => 'Hey!');
让我们更改您的代码
const useSearchState = <T>(mapState?: (state: SearchState) => T) => {
if (mapState) {
// Type 'T' is not assignable to type 'HasSearchState'.
return useHasSearchState((hasState) => mapState(hasState.searchState));
}
return useHasSearchState((hasState) => hasState.searchState);
};
类型检查器现在可以使用,useHasSearchState的类型为(mapState:MapState)=> HasSearchState。添加限制:
const useSearchState = <T extends HasSearchState>(mapState?: (state: SearchState) => T) => {
现在很明显错误
// Type 'string' is not assignable to type 'HasSearchState'.
const useId = () => useSearchState(state => state.id);