打字稿无法正确推断HOC内的this.props

时间:2019-08-13 14:05:16

标签: reactjs typescript

考虑遵循虚拟HOC

interface SelectOption {
  value: string;
  label: string;
}

interface HOCProps {
  value: string | SelectOption;
}

const testHOC = <P extends HOCProps>(Component: React.ComponentType<P>): React.ComponentType<P> =>
  class Wrapper extends React.Component<P> {
    constructor(props: P) {
      super(props);
      console.log(this.props.value);
      console.log(props.value);
  }

  render() {
    return <Component {...this.props} />;
  }
};

打字稿可以按预期识别props.value

  

(属性)HOCProps.value:字符串| SelectOption

但是在this.props.value中,我得到了不同的结果:

  

(属性)值:P [“ value”]

如何修复类型注释,以便打字稿能够正确推断this.props
ps。 codesanbox link to the code in question

1 个答案:

答案 0 :(得分:3)

您在构造函数中看到this.propsprops之间存在差异的原因是,它们实际上是不同的类型。

props在构造函数中键入为P,而this.propsReact.Component中定义为props: Readonly<P> & Readonly<{ children?: ReactNode }>;

Readonly在打字稿库中定义为mapped type,因此您会在将P["value"]从映射类型中拉出时将其悬停。

打字稿维护者multiple times引起了这个问题,fixed引起了这个问题。

但是,由于某种原因,向您显示类型的引擎无法解析这些映射的类型。

使用JetBrains IntelliJ,类型可以正确解析,而在codesandbox中,我仅看到未解析的类型P["value"],它引用映射的类型...

example screenshot

在最小示例中也可以看到问题:

interface Base {
  value: string | number;
}

const test = <T extends Base>(a: T, b: Readonly<T>) => {
  console.log(a.value, b.value);
}

根据维护者的说法,这是打字稿的已知设计限制:https://github.com/microsoft/TypeScript/issues/32932#issuecomment-522353713