英文:
Generate union type from an array
问题
我想从 `ALL_RESPONSE_TYPES` 数组生成联合类型。
具有以下代码:
```typescript
interface MetadataAccepted {
a: string;
b: number;
}
interface MetadataIgnored {
c: number;
d: string;
e: {
a: string
}
}
const ALL_RESPONSE_TYPES = [
['ACCEPTED', { a: '', b: 0 } as MetadataAccepted],
['IGNORED', { c: 0, d: '', e: {a: ''} } as MetadataIgnored],
] as const;
我想创建以下类型:
type ResponseType =
| {
type: 'ACCEPTED';
metadata: {
a: string;
b: number;
};
}
| {
type: 'IGNORED';
metadata: {
c: number;
d: string;
e: { a: string }
};
};
我相信在 TypeScript 中应该可以实现这一点。
<details>
<summary>英文:</summary>
I want to generate union from the `ALL_RESPONSE_TYPES` array.
Having the following code:
```typescript
interface MetadataAccepted {
a: string;
b: number;
}
interface MetadataIgnored {
c: number;
d: string;
e: {
a: string
}
}
const ALL_RESPONSE_TYPES = [
['ACCEPTED', { a: '', b: 0 } as MetadataAccepted],
['IGNORED', { c: 0, d: '', e: {a: ''} } as MetadataIgnored],
] as const;
I want to create the following type:
type ResponseType =
| {
type: 'ACCEPTED';
metadata: {
a: string;
b: number;
};
}
| {
type: 'IGNORED';
metadata: {
c: number;
d: string;
e: { a: string }
};
};
I believe it should be possible to achieve this in typescript.
答案1
得分: 1
你可以创建一个映射数组类型,将ALL_RESPONSE_TYPES
的类型转换为type
/metadata
对象的数组类型,然后使用number
索引进入该类型以获得联合类型。就像这样:
type R<T extends readonly (readonly [any, any])[]> =
{ [I in keyof T]: { type: T[I][0], metadata: T[I][1] } }[number];
R
实用类型将类似[[0, 1], [2, 3], [4, 5]]
的对数数组类型转换为类似[{type:0, metadata:1},{type: 2, metadata: 3},{type: 4, metadata: 5}]
的对象数组,然后索引进入它以获得联合类型{type:0, metadata:1} | {type: 2, metadata: 3} | {type: 4, metadata: 5}
。
当它作用于ALL_RESPONSE_TYPES
的类型时,使用typeof类型查询运算符,它将为您提供所需的ResponseType
:
type ResponseType = R<typeof ALL_RESPONSE_TYPES>;
/* type ResponseType = {
type: "ACCEPTED";
metadata: MetadataAccepted;
} | {
type: "IGNORED";
metadata: MetadataIgnored;
} */
英文:
You can make a mapped array type that transforms the type of ALL_RESPONSE_TYPES
to an array type of type
/metadata
objects, and then index into that type with number
to get a union. Like this:
type R<T extends readonly (readonly [any, any])[]> =
{ [I in keyof T]: { type: T[I][0], metadata: T[I][1] } }[number];
The R
utility type converts an array type of pairs like [[0, 1],[2, 3],[4, 5]]
into an array of objects like [{type:0, metadata:1},{type: 2, metadata: 3},{type: 4, metadata: 5}]
and then indexes into it to get the union {type:0, metadata:1} | {type: 2, metadata: 3} | {type: 4, metadata: 5}
.
And when it acts on the type of ALL_RESPONSE_TYPES
, using the typeof
type query operator, it gives you the desired ResponseType
:
type ResponseType = R<typeof ALL_RESPONSE_TYPES>;
/* type ResponseType = {
type: "ACCEPTED";
metadata: MetadataAccepted;
} | {
type: "IGNORED";
metadata: MetadataIgnored;
} */
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论