首页 > 解决方案 > TS 在返回的对象中定义动态属性的类型

问题描述

所以我从 API 中获取这种数据。

{
   data: {
     [dynamicPropertyName]: { // property name changes depending on endpoint 
       elements: [], // this also dynamically change depending on the endpoint
       total: 0
     }
   }
}

现在我想出了一种方法来解决在数据属性中具有动态属性的问题,尽管我似乎无法将正确的类型传递给elements属性。

export interface Result<T> {
  elements: T[];
  total: number;
}

export type SearchResultData< T > = {
  [ k in keyof T ]: Result<T>
};

export interface SearchResult<T> {
  data: SearchResultData<T>;
}


interface User {
  name: string;
}

export interface UsersResult {
  users: User[]
}

export type UsersSearchResult = SearchResult<UsersResult>

const a: UsersSearchResult = {
  data: {
    users: {
      elements: [{
        /// here it's resolving the UserResult Type instead of User
      }],
      total: 0
    }
  }
}

我想避免两次定义 User 类型,例如export type UsersSearchResult = SearchResult<UsersResult, USer>.

有什么方法可以从T[k]我传递给的类型中提取类型SearchResult<T>吗?

就像是

export type SearchResultData< T > = {
      [ k in keyof T ]: Result<T[k]> /// ????
    };

更新:

原来只是我的愚蠢错误。只是为了其他人遇到同样的问题。这是更新的代码。

export interface Result<T> {
  elements: T;
  total: number;
}

export type SearchResultData< T > = {
  [ k in keyof T ]: Result<T[k]>
};

标签: typescript

解决方案


您需要指定elements将属于同一键的对象。如下所示,我只是将元素设置为表示的键的值k

(另外,我在多种类型中上下查找有点困难,所以我创建了一个统一的界面,但它也应该适用于您的代码)。

TS游乐场

export interface SearchResult<T> {
  data: {
    [k in keyof T]: {
      elements: T[k];
      total: number;
    };
  };
}

// Example
interface User {
  name: string;
}

export interface UsersResult {
  users: User[];
}

export type UsersSearchResult = SearchResult<UsersResult>;

const a: UsersSearchResult = {
  data: {
    users: {
      elements: [
        {
          name: "wwe",
        },
        {
          name: "wwe",
        },
      ],
      total: 0,
    },
  },
};

推荐阅读