繁体   English   中英

如何使TypeScript正确键入对泛型函数的检查调用,然后依次调用具有泛型类型参数的函数?

[英]How can get TypeScript to correctly type check call to a generic function that in turns calls a function with a generic type parameter?

我正在尝试编写与此非常相似的代码:

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类型检查中使用它?

真实代码的上下文是在redux-hooks库的帮助下使用Hooks进行 React

我觉得这应该正确输入check,但是显然我误会了一些东西。

将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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM