[英]Use name of type in other types on TS
I have types:我有类型:
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",
}
base on this types, how i can create type something like that (the part of the Type below is pseudocode):基于这种类型,我如何创建类似的类型(下面的类型部分是伪代码):
type TResponse<T> = {
data: T extends TUser ? TUser[] : {[TDataMethod[T]]: T}
time: string,
}
for objects对于对象
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"
}
or i have one way - use extends declaration?或者我有一种方法 - 使用扩展声明?
It is possible with some Typescript "programming".一些 Typescript “编程”是可能的。
For example, I have these interfaces.例如,我有这些接口。
interface User {
name: string;
age: number;
}
interface Bot {
name: string;
author: string;
}
The Metadata
should be an array so we could iterate from it. Metadata
应该是一个数组,以便我们可以从中迭代。
type Metadata = [
{
name: 'users'; // here's the property
type: User; // here's the type
},
{
name: 'bots';
type: Bot;
}
];
We don't actually could iterate from it.我们实际上不能从中迭代。 So, create an helper named ArrayUnshift
which will unshift (remove first item) from the generic type.因此,创建一个名为ArrayUnshift
的助手,它将从泛型类型中取消移位(删除第一项)。 If the generic type ( Array
) is [first, ...rest]
, then return the rest so the first item is removed.如果通用类型 ( Array
) 是[first, ...rest]
,则返回 rest 以便删除第一项。
type ArrayUnshift<Array extends any[]> =
Array extends [infer First, ...infer Rest] ?
Rest : never;
Then we could itearate the Metadata
.然后我们可以迭代Metadata
。 If the first Metadata.type
is equal to generic type, then return the Metadata.name
, if not recursive to itself but unshift the 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>>;
Last, create ResponseData
with MetadataProperty<T>
as its property.最后,使用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
}
}
There's a repo that related to this topic, take a look to Type Challenges .有一个与此主题相关的回购协议,请查看Type Challenges 。
EDIT: Or you could simply use Extract utility as being said by @caTS .编辑:或者您可以简单地使用@caTS所说的 Extract 实用程序。
You don't need to "iterate" over them;您不需要“迭代”它们; just get the elements as a union and use Extract:
Extract<Metadata[number], { type: T }>["name"]
.只需将元素作为联合获取并使用 Extract:Extract<Metadata[number], { type: T }>["name"]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.