I am attempting to transcribe this class originally written in JavaScript.
Here is the code snippet provided.
type SchemaDefinition<Schema> = {[Key in keyof Schema]: Schema[Key][] | {[K in keyof Schema[Key]]: SchemaDefinition<Schema[Key][K]>}};
type Middlewares<Schema> = {[Key in keyof Schema]: (value: Schema[Key]) => Schema[Key] | {[K in keyof Schema[Key]]: Middlewares<Schema[Key][K]>}};
class ObjectGenerator<Schema> {
private schemaDefinition: SchemaDefinition<Schema>;
constructor(schemaDefinition: SchemaDefinition<Schema> = {} as SchemaDefinition<Schema>) {
this.schemaDefinition = schemaDefinition;
}
generate(middlewares: Middlewares<Schema> = {} as Middlewares<Schema>): Schema {
const {schemaDefinition} = this;
return Object.entries(schemaDefinition).reduce((schema, [property, values]) => {
if (Array.isArray(values)) {
return {...schema, [property]: (middlewares[property] || ((x: any): any => x))(values[Math.floor(Math.random() * values.length)])};
} else if (typeof values === "object") {
return {...schema, [property]: new ObjectGenerator(values).generate(middlewares[property])};
}
return schema;
}, {} as Schema);
}
}
The error message I encountered reads as follows:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Middlewares<Schema>'. No index signature with a parameter of type 'string' was found on type 'Middlewares<Schema>'
My expectation is for TypeScript not only to infer the types accurately during compile time (such as for the Schema
that transforms into a SchemaDefinition
) but also to support recursive calls and still predict the types of nested properties in the final output. This way, clients would receive warnings when trying to access a non-existent nested property, invoking a middleware on a property that does not exist, or using a wrong type in the middleware call.