首页 > 解决方案 > 如何满足打字稿中的扩展类型接口

问题描述

嗨,我想为 api 请求制作可重用的钩子这是我的代码:

interface DataResponse<Data> {
  data: Data[];
}

export const useRequestInfiniteHooks = <T extends DataResponse<T>>() => {
  const url = "/lms/class/all";

  const result = apiRequest()
  const mappedData: T['data'] = mappingData()

  return {data: mappedData};
};

type ClassesResponse = {
  data: {
    id: string;
    title: string;
  }[];
  total: number;
};

const MantapComponent = () => {
  const { data } = useRequestInfiniteHooks<ClassesResponse>();
};

我希望数据包含传递给通用调用的类型,即 . 它确实已经得到了类型,但是当我调用这个钩子时它并不满意。

这是错误响应

挂机电话

Type 'ClassesResponse' does not satisfy the constraint 'DataResponse<ClassesResponse>'.
  Types of property 'data' are incompatible.
    Type '{ id: string; title: string; }[]' is not assignable to type 'ClassesResponse[]'.
      Type '{ id: string; title: string; }' is missing the following properties from type 'ClassesResponse': data, totalts(2344)
type ClassesResponse = {
    data: {
        id: string;
        title: string;
    }[];
    total: number;
}

我应该怎么做才能满足这个钩子调用?

我尝试这样称呼它,但仍然出现错误

在此处输入图像描述

Type 'DataResponse<ClassesResponse>' does not satisfy the constraint 'DataResponse<DataResponse<ClassesResponse>>'.
  Type 'ClassesResponse' is not assignable to type 'DataResponse<ClassesResponse>'.
    Types of property 'data' are incompatible.
      Type 'Class[]' is not assignable to type 'ClassesResponse[]'.
        Type 'Class' is missing the following properties from type 'ClassesResponse': data, totalts(2344)
type ClassesResponse = {
    data: Class[];
    total: number;
}

我已经阅读了这里的文档 https://www.typescriptlang.org/docs/handbook/2/generics.html

他们只告诉您如何使用泛型创建函数,而不是如何正确调用它以使其对您传递的类型感到满意。

所以这就是我的问题如何满足那个钩子/函数调用?

标签: typescriptgenericsinterfacetypescript-types

解决方案


你有一种自我参照(可能是无限的?)通用约束。您还需要ClassesResponse扩展自DataResponse. 以下可以工作:

interface IData {
  id: string
}

interface IDataResponse<IData> {
  data: IData[]
}

export const useRequestInfiniteHooks = <T extends IDataResponse<IData>>() => {
  const url = "/lms/class/all"

  const result = apiRequest()
  const mappedData: T['data'] = mappingData()

  return { data: mappedData }
};

class ClassesResponse implements IDataResponse<Data> {
  data: Data[];
  total: number
}

class Data implements IData {
  id: string
  title: string
}

const MantapComponent = () => {
  const { data } = useRequestInfiniteHooks<ClassesResponse>()
}

推荐阅读