I have the following conditional type:
type ComplexType<T> = {
[key in keyof T]: T[key] extends {
type: unknown
schema?: unknown
}
?
| (T[key]['schema'] extends object
? ComplexType<T[key]['schema']>
: never)
| TypeFromConstructor<T[key]['type']>
: TypeFromConstructor<T[key]> | undefined
}
type TypeFromConstructor<T> = T extends StringConstructor
? string
: T extends NumberConstructor
? number
: T extends BooleanConstructor
? boolean
: T extends DateConstructor
? Date
: T extends ArrayConstructor
? never
: T extends ObjectConstructor
? never
: unknown
If I now use it on an object like this:
const schema = {
test: {
type: Array,
schema: [{
type: Object,
schema: {
id: String,
},
}],
},
}
type testType = ComplexType<typeof schema>
testType yields smth like: { test: Array<{id: string}> }, but I would have expected smth like { test: { '0': {id: string}} } because I never check if the type of schema is an array. I understand that iterating over the keys will also iterate over the array elements, but how can it infer it being an array, when the type does not check for it? And why does it not include the default array properties like length, etc into the type? Does it have smth to do with that an array is just an object in javascript?