我想将一种 struct 类型转换为另一种 struct 类型.源 struct 是一个对象,它可能包含由点分隔的属性键.我想将这些"逻辑组"扩展为子对象.
因此:
interface MyInterface {
'logicGroup.timeout'?: number;
'logicGroup.serverstring'?: string;
'logicGroup.timeout2'?: number;
'logicGroup.networkIdentifier'?: number;
'logicGroup.clientProfile'?: string;
'logicGroup.testMode'?: boolean;
station?: string;
other?: {
"otherLG.a1": string;
"otherLG.a2": number;
"otherLG.a3": boolean;
isAvailable: boolean;
};
}
对此:
interface ExpandedInterface {
logicGroup: {
timeout?: number;
serverstring?: string;
timeout2?: number;
networkIdentifier?: number;
clientProfile?: string;
testMode?: boolean;
}
station?: string;
other?: {
otherLG: {
a1: string;
a2: number;
a3: boolean;
},
isAvailable: boolean;
};
}
__
(EDIT)当然,上述两种 struct 基于真实的Firebase远程配置Typescript转置,不能有任意的props (没有索引签名)或键冲突(我们不希望有任何logicGroup
和logicGroup.anotherProperty
).
属性可以是可选的(logicGroup.timeout?: number
),我们可以假设,如果logicGroup
中的所有属性都是可选的,那么logicGroup
本身也可以是可选的.
我们确实希望一个可选属性(logicGroup.timeout?: number
)将保持相同的类型(logicGroup: { timeout?: number }
),而不是成为强制属性,并可能显式接受undefined
作为值(logicGroup: { timeout: number | undefined }
).
我们希望所有属性都是对象、字符串、数字、布尔值.无数组、无并集、无交点.
我try 过使用映射类型、密钥重命名、条件类型等等.我想出了这个局部解决方案:
type UnwrapNested<T> = T extends object
? {
[
K in keyof T as K extends `${infer P}.${string}` ? P : K
]: K extends `${string}.${infer C}` ? UnwrapNested<Record<C, T[K]>> : UnwrapNested<T[K]>;
}
: T;
哪doesn't个输出我想要的:
type X = UnwrapNested<MyInterface>;
// ^? ===> { logicGroup?: { serverString: string | undefined } | { testMode: boolean | undefined } ... }
因此,有两个问题:
- logicGroup是一个分布式联合体
- logicGroup属性保留
| undefined
,而不是实际的可选属性.
因此,我试图通过服装K
%的价值来阻止分销:
type UnwrapNested<T> = T extends object
? {
[
K in keyof T as K extends `${infer P}.${string}` ? P : K
]: [K] extends [`${string}.${infer C}`] ? UnwrapNested<Record<C, T[K]>> : UnwrapNested<T[K]>;
}
: T;
这是输出,但仍然不是我想要的:
type X = UnwrapNested<MyInterface>;
// ^? ===> { logicGroup?: { serverString: string | boolean | number | undefined, ... }}
一个问题消失,另一个问题出现.因此,问题是:
- 所有子属性都是同一"逻辑组"中所有可用值的a类并集
- 所有子属性都保留
| undefined
,而不是实际的可选属性.
我也try 过使用其他选项来过滤类型等等,但我不知道我缺少了什么.
我还找到了https://stackoverflow.com/a/50375286/2929433,它实际上是独立工作的,但我无法将它集成到我的公式中.
我不明白什么?