Big types refactor
Types updateโ
We have a big update in version 0.49.0 affecting the main types used in the CMS.
The signature of EntitySchema<Key extends string = string>
has changed to
EntitySchema<M>
where M
is your model type like:
import { buildSchema } from "@camberi/firecms";
type Product = {
name: string;
price:number;
}
const productSchema = buildSchema<Product>({
// ...
properties:{
name: {
dataType: "string",
// ...
},
// ...
}
// ...
});
This change propagates to all the rest of the types used internally and in
the public API, especially to all the types that had EntitySchema
as a generic
type argument.
For example EntityValues
(representing the data related to an entity) had the
signature EntityValues<S extends EntitySchema<Key>, Key extends string>
and now
it is simply EntityValues<M>
. You may use EntityValues
or any other type
that includes a schema as a type if you have callbacks in place or have
implemented custom views.
This affects in an equal way all the types that are exported. In order to
migrate to the new version you need to make sure that you don't have any
references like EntityCollection<typeof productSchema>
, like the ones we had
in the previous examples. In that case you can create your Product
type if
you want better type checking or simply remove it.
Motivationโ
Let's face it, the type system related to schemas until now was a mess.
It had become overcomplicated and was not providing enough type information in the callbacks. Not it is much straightforward.
Robustnessโ
I have always found it annoying all the Javascript frameworks that use the
module.exports
system for configuration. I find myself going always back
and fort from the IDE to their website to get the information I need, even if
I have an idea.
Configuration as code with a strong type system is a whole other level.
The new system is now able to tell you exactly what you are configuring wrong,
or suggest the props you are looking for. The following is a configuration
error because we are assigning the multiline
config, which applies only to
strings, to a number property:
// ...
name: {
dataType: "number",
title: "Name",
config: {
multiline: true
},
validation: { required: true }
}
// ...
So it indicates a type error:
Migration examplesโ
For example, if you had a callback including EntityValues
, you would know the
property keys you had defined, but not the types.
import { buildSchema } from "@camberi/firecms";
type Product = {
name: string;
price: number;
}
export const productSchema = buildSchema<Product>({
name: "Product",
onPreSave: ({
schema,
path,
id,
values,
status
}) => {
// Now values is of type `Product`
console.log(values);
return values;
},
properties: {
name: {
dataType: "string",
title: "Name"
},
price: {
dataType: "number",
title: "Price"
}
}
});
With this update you get a complete type system in all your callbacks, which will help prevent errors.
Use without specifying the typeโ
There is a way to get the same type validation without indicating the type
explicitly. You can wrap each property with buildProperty
to get the same result
import { buildSchema, buildProperty } from "@camberi/firecms";
export const productSchema = buildSchema({
name: "Product",
onPreSave: ({
schema,
path,
id,
values,
status
}) => {
// Now values is of type `{ name: string; price: number; }`, so
// equivalent to the previous example
console.log(values);
return values;
},
properties: {
name: buildProperty({
dataType: "string",
title: "Name"
}),
price: buildProperty({
dataType: "number",
title: "Price"
})
}
});
This way of building your schemas is not encouraged, but it may be useful for simplifying your migration.
In case you need to retrieve the type of the schema you have created, we now include
a utility type called InferSchemaType
that could be useful if you had code
like buildCollection<typeof productSchema>
, which now would simply turn into
buildCollection<InferSchemaType<typeof productSchema>>
We know that it can be a bit frustrating to migrate code to a newer version and fix breaking changes, but we are convinced that this is a change for the better, making our life and our users easier ๐
Affected types and methodsโ
All the following types and methods have seen their types changed from
<S extends EntitySchema<Key>, Key extends string>
to <M>
- EntityCollection
- AdditionalColumnDelegate
- PermissionsBuilder
- ExtraActionsParams
- FilterValues
- EntityCustomView
- EntityCustomViewParams
- EntitySaveProps
- EntityDeleteProps
- Entity
- EntityValues
- FieldProps
- FormContext
- CMSFormFieldProps
- Properties
- PropertyBuilderProps
- PropertyBuilder
- PropertyOrBuilder
- listenCollection
- fetchCollection
- fetchEntity
- listenEntity
- listenEntityFromRef
- createEntityFromSchema
- saveEntity
And some other components that are only used in advaced use cases.