I know there is a way to generate a type dynamically: Typescript dynamically create types based on object
But I can't find a way to make some properties of the dynamically generated type optional.
For example, say I have a object
const obj = {
keyName1: {
type: 'string',
required: true
},
keyName1: {
type: 'string',
required: false
},
}
How do I make a type based on this object? Given that some properties are optional (if required is false).
If I simply have this object:
const obj = {
keyName1: 'string'
}
I could make a type with:
type Generate<T> = T;
type Generated = Generate<typeof myObj>
But with optional parameters, I don't know how...
CodePudding user response:
You'll first need a utility type mapping each type string (eg 'string'
) to its type (string
).
Then, map the object properties and do Obj[K]['required'] extends true ?
to conditionally check whether to alternate with undefined
or not. See this answer for how to separate out the optional properties from the non-optional properties in the new object.
const obj = {
keyName1: {
type: 'string',
required: true
},
keyName2: {
type: 'number',
required: false
},
} as const;
type Obj = typeof obj;
type TypesByTypeof = {
'string': string;
'number': number;
}
type ObjType = {
[key in keyof Obj as Obj[key]['required'] extends true ? key : never]: TypesByTypeof[Obj[key]['type']]
} & {
[key in keyof Obj as Obj[key]['required'] extends false ? key : never]?: TypesByTypeof[Obj[key]['type']]
}
Result:
type ObjType = {
readonly keyName1: string;
} & {
readonly keyName2?: number | undefined;
}