TypeScript包装函数,用于只读useState

时间:2019-11-23 22:46:37

标签: typescript react-hooks

我想做一个包装器函数useStateRO,将所有属性标记为只读,以便只能使用setState更改状态,但不能为返回值创建正确的类型。

CodeSandBox example.

import React, { useState, useEffect } from "react";
import { render } from "react-dom";

type DeepReadonly<T> = T extends (infer R)[]
  ? DeepReadonlyArray<R>
  : T extends Function
  ? T
  : T extends object
  ? DeepReadonlyObject<T>
  : T;

function useStateRO<T>(
  props: T
): [DeepReadonly<T>, React.Dispatch<React.SetStateAction<T>>] {
  return useState<DeepReadonly<T>>(props); // fix needed
}

interface IX {
  x: number;
}

function App() {
  const [test, setTest] = useState<IX>({ x: 1 });

  useEffect(() => {
    setTest({ x: 2 });
  }, []);
  console.log(test.x);
  test.x = 5; // should be error

  return <div>Hi</div>;
}

render(<App />, document.getElementById("root"));

1 个答案:

答案 0 :(得分:1)

一如既往,在制作沙箱并提出问题后自己寻找解决方案:/

function useStateRO<T>(props: T): [DeepReadonly<T>, React.Dispatch<React.SetStateAction<T>>] {
  return useState(props) as [DeepReadonly<T>, React.Dispatch<React.SetStateAction<T>>]
}