繁体   English   中英

在 TS 上使用其他类型中的类型名称

[英]Use name of type in other types on TS

我有类型:

type TUser= {
   id: number,
   name: string,
}

type TFields = {
   value: number,
   name: string,
   otherField: string,
}

type TTask = {
   id: number,
   title: string,
}

type TDataMethod = {
   "TField": "fields",
   "TTask": "tasks",
}

基于这种类型,我如何创建类似的类型(下面的类型部分是伪代码):

type TResponse<T> = {
   data: T extends TUser ? TUser[] : {[TDataMethod[T]]: T}
   time: string,
}

对于对象

const userResponse: TResponse<TUser> = {
   data: [
      id: 1,
      name: "John",
   ],
   time: "13 august 2022"
}

const taskResponse: TResponse<TTask> = {
   data: {
      tasks: {
         id: 1,
         title: "Some task",
      }
   },
   time: "14 august 2022"
}

或者我有一种方法 - 使用扩展声明?

一些 Typescript “编程”是可能的。

例如,我有这些接口。

interface User {
  name: string;
  age: number;
}

interface Bot {
  name: string;
  author: string;
}

Metadata应该是一个数组,以便我们可以从中迭代。

type Metadata = [
  {
    name: 'users';  // here's the property
    type: User;     // here's the type
  },
  {
    name: 'bots';
    type: Bot;
  }
];

我们实际上不能从中迭代。 因此,创建一个名为ArrayUnshift的助手,它将从泛型类型中取消移位(删除第一项)。 如果通用类型 ( Array ) 是[first, ...rest] ,则返回 rest 以便删除第一项。

type ArrayUnshift<Array extends any[]> = 
  Array extends [infer First, ...infer Rest] ?
    Rest : never;

然后我们可以迭代Metadata 如果第一个Metadata.type等于泛型类型,则返回Metadata.name ,如果不是递归到自身但取消移动Metadata

type MetadataProperty<T extends any, Data extends any[] = Metadata> =
  Data[0]['type'] extends T ?
    Data[0]['name'] : MetadataProperty<T, ArrayUnshift<Data>>;

最后,使用MetadataProperty<T>作为其属性创建ResponseData

interface ResponseData<T extends object> {
  time: string;
  data: MetadataProperty<T> extends string ? {
    [Key in MetadataProperty<T>]: T;
  } : {
    string: T;  // fallback to avoid error
  }
}

有一个与此主题相关的回购协议,请查看Type Challenges


编辑:或者您可以简单地使用@caTS所说的 Extract 实用程序。

您不需要“迭代”它们; 只需将元素作为联合获取并使用 Extract: Extract<Metadata[number], { type: T }>["name"]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM