Based on his answer you can define own types. So you can define there '?string' too. But I guess it will require to specify the property anyway with value of string or undefined.
type MapSchemaTypes = {
string: string;
integer: number;
'?string': string | undefined;
}
I was managed to do it like that:
const pattern = {
"names": {
"firstName": "string",
"lastName": "?string"
},
"age": "number",
"name": "string",
"lastName": "?string",
} as const;
type FILTER_PROPS<Base, Condition> = {
[Key in keyof Base]: Base[Key] extends Condition ? Key : never;
}[keyof Base];
type Pattern<T> = {
[K in FILTER_PROPS<T, '?string' | '?number'>]?:
T[K] extends '?number' ? number
: T[K] extends '?string' ? string
: never
} & {
[K in FILTER_PROPS<T, 'string' | 'number' | {[SK in keyof any]: any}>]:
T[K] extends 'number' ? number
: T[K] extends 'string' ? string
: T[K] extends {} ? Pattern<T[K]>
: never
};
const a: Pattern<typeof pattern> = {
names: {
firstName: 'Test',
},
name: 'required',
age: 123,
};