如何解决Typescript对React Hooks中使用mobx时props的类型检查?

最外层组件传入 mobx 中的 stores:

import { stores } from "@/stores";
import { Provider } from "mobx-react";
ReactDOM.render(
  <Provider {...stores}>
    <App />
  </Provider>,
  document.getElementById("app") as HTMLElement
);

中间组件 App:

import React from "react";
import "./app.scss";
import Cards from "@/floors/Cards";
const App = () => {
  return (
    <div className="welcome-container">
      <Cards />
    </div>
  );
};
export default App;

子组件:如何定义 store 的类型,由于 store 相当于 props 传入的,如果定义了 props 类型,则父组件''就会报错,因为没有传入 TS 规定的 store 类型;

interface IWelcomeProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards: React.FC<IWelcomeProps> = (props: IWelcomeProps) => {
  const { appStore, myPlusStore } = props;
};
export default inject("appStore", "myPlusStore")(observer(Cards));

解决方法:

一:父组件 Cards 有自己的 props 时:

让 store 定义的 TS 类型 IWelcomeProps 继承于 MyComponentProps,这样 IWelcomeProps 有了所有的 props 类型,

但是子组件传入的类型是不包含 props 的 MyComponentProps 类型;

然后在组件内部让 props 在断言成 IWelcomeProps

这样传入的 props 只是父组件真正的 props 类型;而内部组件的 props 被断言成包含了 store 和父组件 props 的类型

interface MyComponentProps {
  name?: string;
}

interface IWelcomeProps extends MyComponentProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards: React.FC<MyComponentProps> = (props: MyComponentProps) => {
  const _props = props as IWelcomeProps;
  const { appStore, myPlusStore } = _props;
};
export default inject("appStore", "myPlusStore")(observer(Cards));

二:父组件没有 props 的时候

定义了 store 类型 IWelcomeProps,在传入 props 的时候使用 Partial<>,将其改为可选属性,然后在子组件中使用断言再将其改为真正的 store 属性,骗过 ts 检查

import React, { useState, useEffect } from "react";
import { inject, observer } from "mobx-react";
import { GlobalStores } from "@/stores";

interface IWelcomeProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards = (props: Partial<IWelcomeProps>) => {
  const _props = props as IWelcomeProps;
  const { appStore, myPlusStore } = _props;
  const [currList, setCurrList] = useState("he");

  return (
    <div className="welcome-container">
      <p>我的初始名字是:{appStore.initName}</p>
    </div>
  );
};
export default inject("appStore", "myPlusStore")(observer(Cards));

参考文章:https://zhuanlan.zhihu.com/p/33406998