英文:
Typescript mapped types not generating correct output
问题
我正在处理一个项目,我希望允许用户选择从特定类型中获取特定字段。给定以下类型:
type DataType = {
field1: number;
field2: string;
field3?: {
subField1: number;
subField2: string;
};
field4?: number[];
};
我想将这个类型转换为以下类型:
type DataTypeFlags = {
field1?: boolean;
field2?: boolean;
field3?: {
subField1?: boolean;
subField2?: boolean;
};
field4?: boolean;
};
我已经提出了以下解决方案,它大部分工作正常,但如果原始类型中的字段之一具有数组字段,它会出现问题:
type Flags<T extends Record<string, any>> = {
[K in keyof T]: T[K] extends Record<string, any> | undefined ? Flags<T[K]> : boolean;
};
type DataTypeFlags = Flags<DataType>;
// 输出:
// {
// field1?: boolean; | undefined // 正常
// field2?: boolean; | undefined // 正常
// field3?: {
// subField1?: boolean | undefined; // 正常
// subField2?: boolean | undefined; // 正常
// } | undefined;
// field4?: (boolean | undefined)[] | undefined; // 出现问题
// }
为什么我的 Flags
类型在目前的状态下不起作用?是否有解决方法,还是这是 TypeScript 的限制?
英文:
I'm working on a project where I want to allow the user to choose specific fields to get from a specific type. Given the following type:
type DataType = {
field1: number;
field2: string;
field3?: {
subField1: number;
subField2: string;
};
field4?: number[];
};
I want to convert this type to the following type:
type DataTypeFlags = {
field1?: boolean;
field2?: boolean;
field3?: {
subField1?: boolean;
subField2?: boolean;
};
field4?: boolean;
};
I have come up with the following which mostly works well, but breaks if one of the fields from the original type has a field that is an array:
type Flags<T extends Record<string, any>> = {
[K in keyof T]: T[K] extends Record<string, any> | undefined ? Flags<T[K]> : boolean;
};
type DataTypeFlags = Flags<DataType>;
// outputs:
// {
// field1?: boolean; | undefined // good
// field2?: boolean; | undefined // good
// field3?: {
// subField1?: boolean | undefined; // good
// subField2?: boolean | undefined; // good
// } | undefined;
// field4?: (boolean | undefined)[] | undefined; // breaks here
// }
Why does my Flags
type not work in the state that it's in? Is there a solution to this or is this a limitation of Typescript?
答案1
得分: 2
代码部分不提供翻译。
英文:
It seems that the problem here is the use of optional types.
One possible solution is to use NonNullable
wrappers to exclude undefined
from the given type. Here's an example:
type DataType = {
field1: number;
field2: string;
field3?: {
subField1: number;
subField2: string;
};
field4?: number[];
};
type Flages<T extends Record<string, unknown>> = {
[P in keyof T]+?: NonNullable<T[P]> extends Record<string, unknown> ? Flages<NonNullable<T[P]>> : boolean
}
const example: Flages<DataType> = {
field1: false,
field3: {
subField1: false
},
field4: true
}
PS +?
modifier will explicitly make a property optional
答案2
得分: 0
以下是代码部分的翻译:
type Flags<T extends Record<string, any>> = {
[K in keyof T]: T[K] extends (any[]|undefined) ? boolean : T[K] extends Record<string, any> | undefined ? Flags<NonNullable<T[K]>> : boolean;
};
请注意,这是 TypeScript 代码,用于定义一个 Flags 类型。如果你需要进一步的解释或有其他问题,请随时提出。
英文:
What about just handling the use case of arrays ?
type Flags<T extends Record<string, any>> = {
[K in keyof T]: T[K] extends (any[]|undefined) ? boolean : T[K] extends Record<string, any> | undefined ? Flags<NonNullable<T[K]>> : boolean;
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论