So we are developing a CMS for Firestore and have created a schema system in Typescript. Users can define schemas and the data is fetch from the database with the specified schema properties.
The basic types we use:
export interface EntitySchema {
properties: Record<string, any>;
}
interface Entity<S extends EntitySchema> {
values: {
[K in keyof S["properties"]]: any
}
}
So we have the EntitySchema the developer defines, and the Entity which are the objects he gets back when fetching from the database. I include a sample method that populates the values defined in the schema:
function getEntity<S extends EntitySchema>(
schema: S
): Entity<S> {
return {
values: Object.keys(schema.properties)
.map((key) => ({ [key]: undefined }))
.reduce((a: any, b: any) => ({ ...a, ...b }), {})
};
}
The problem I am facing is that Typescript is not inferring properly the keys from the schema in the entity:
const sampleSchema: EntitySchema = {
properties: {
name: "Name"
}
};
const entityA: Entity<typeof sampleSchema> = getEntity(sampleSchema);
const shouldFail = entityA.values.notExistingProperty; // doesn't fail
// also creating the entity directly doesn't work as expected
const entityB: Entity<typeof sampleSchema> = {
values: {
name: "aaa", // this is ok
shouldFailToo: "bbb" // doesn't fail
}
};
Either if I use the simulated DB method or initialise the Entity with a supplied schema directly, the values field in the Entity is just treated as a Record<string, any> and the keys of the schema are ignored. I feel I am missing something here. Any help appreciated!