我想知道在类型脚本和映射类型中有什么可用来创建将应用初始类型中定义的只读和可选属性的映射类型.举个例子会更容易解释.
我已经做了一个尽可能简单的例子,从定义为
type PropertyAttributes = {
readonly optional?: boolean;
readonly readonly?: boolean;
readonly value: string; //this would be something else but to simplify example like this
};
type ObjectDefinition = Record<string, PropertyAttributes>
在某种程度上,这是一个模板,我想用它来创建一个类型.目前,我有这个解决方案,通过创建4个不同的类型和更少的组合它们,工作得相当好.
//Four types corresponding to 4 types of objects
type ReadonlyRequired<O extends ObjectDefinition> = {
+readonly [K in keyof O as O[K]["readonly"] extends true
? O[K]["optional"] extends true
? never
: K
: K]: O[K];
};
type ReadonlyOptional<O extends ObjectDefinition> = {
+readonly [K in keyof O as O[K]["readonly"] extends true
? O[K]["optional"] extends true
? K
: never
: never]?: O[K] | undefined;
};
type MutableRequired<O extends ObjectDefinition> = {
-readonly [K in keyof O as O[K]["readonly"] extends true
? never
: O[K]["optional"] extends true
? never
: K]: O[K];
};
type MutableOptional<O extends ObjectDefinition> = {
-readonly [K in keyof O as O[K]["readonly"] extends true
? never
: O[K]["optional"] extends true
? K
: never]?: O[K] | undefined;
};
//Expand Util
export type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
//Put them all together
type Combine<O extends ObjectDefinition> = Expand<
ReadonlyRequired<O> &
ReadonlyOptional<O> &
MutableRequired<O> &
MutableOptional<O>
>;
最后是一个类型,我认为它与问题的核心无关,但它将结果类型映射为获取对象
//simple maps the Object to value preserving keys since homomorphic as I understand
type MapToValue<O extends ObjectDefinition> = {[K in keyof O]: NonNullable<O[K]>["value"]} //need NonNullable for optional types or infered as unknown
type ToObj<O extends ObjectDefinition>=MapToValue<Combine<O>>
这很好用,有点长,唯一的问题是顺序不会被保留,因为我们必须拆分它.我只是想知道有没有人能想出不同的方法?
或者你能想到的任何微小的改进都将是令人惊叹的.
这里是playground 链接typescript playground
谢谢