【问题标题】:Record<string, any> to {name: string} in typescript在打字稿中记录 <string, any> 到 {name: string}
【发布时间】:2022-01-04 16:50:23
【问题描述】:

我有一个自定义反应挂钩来执行 API 调用:

const useFetch: (string) => Record<string, any> | null = (path: string) => {
  const [data, setData] = useState<Record<string, any> | null>(null);

  var requestOptions: RequestInit = {
    method: "GET",
    redirect: "follow",
  };
  const fetcher = async () => {
    const res = await fetch(
      process.env.REACT_APP_API_ENDPOINT + path,
      requestOptions
    );
    const json = await res.json();
    setData(json.data);
  };
  useEffect(() => {
    fetcher();
  }, [path]);
  return data;
};

我的问题是我使用这个钩子来调用许多不同的端点,所以我无法在钩子中指定data 的类型。但是当我调用钩子时,我知道该特定端点的数据是什么,所以我想为存储返回值的变量指定一个类型,例如:

const data: { name: string } | null = useFetch('/example-end-point');

这是我想要实现的,但我得到这个错误:Property 'name' is missing in type 'Record&lt;string, any&gt;' but required in type '{ name: string; }'.

使用any 作为返回类型是可行的,但如果有任何其他方法可以实现这一点,我不想诉诸于此。

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    这是 Generic Types 可以解决的问题,您完全可以允许将变量类型传递到您的单个钩子中,只需重新编写一点代码。

    看看...

    const useFetch: <T>(string) => Record<T> | null = (path: string) => {
      const [data, setData] = useState<Record<T> | null>(null);
    
      var requestOptions: RequestInit = {
        method: "GET",
        redirect: "follow",
      };
      const fetcher = async () => {
        const res = await fetch(
          process.env.REACT_APP_API_ENDPOINT + path,
          requestOptions
        );
        const json = await res.json();
        setData(json.data);
      };
      useEffect(() => {
        fetcher();
      }, [path]);
      return data;
    };
    

    然后当您调用它时,您可以执行以下操作。

    type MyData = {
      name: string,
    }
    const data: MyData | null = useFetch<MyData>('/example-end-point');
    

    【讨论】:

    • 看来你应该用T替换Record&lt;string, T&gt;
    • @Andrei 不仅可以,而且应该:服务器响应不一定是对象类型。
    【解决方案2】:

    您可能想使用unknown 而不是any 然后通过执行一些类型保护来缩小其他地方的类型,即

    const useFetch: (string) => unknown = (path: string) => {
    ...
    
    
    const user = useFetch('/example-end-point')
    
    if (!user || !user.name) throw new Error("Bad data")
    
    const data: { name: string } = user
    

    这样您就可以进行运行时数据检查以及类型检查。

    【讨论】:

      猜你喜欢
      • 2021-03-13
      • 1970-01-01
      • 2021-11-09
      • 2017-06-07
      • 2017-04-14
      • 2020-04-22
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多