dynamodb-toolbox
dynamodb-toolbox copied to clipboard
Dynamically generated types for output of Entity.parse()
This idea was inspired by how Redux Toolkit allows you to define types from your reducers without having to write everything twice (see: https://redux-toolkit.js.org/tutorials/advanced-tutorial, search page for "ReturnType")
The same strategy could be applied to creating an Entity and then defining a type for the output of YourEntity.parse()
:
const YourEntity = new Entity({
name: 'yourEntity',
table: Table,
attributes: {
something: {
partitionKey: true,
type: 'string',
},
somethingelse: {
sortKey: true,
type: 'string',
},
...
},
});
// Better usage
type YourEntityAttributes = ReturnType<typeof YourEntity.parse>;
// WET usage
interface YourEntityAttributes {
something: string,
somethingelse: string,
...
}
I'm not sure if the current implementation of parse()
is understandable by TypeScript to the same level of accuracy as it is in Redux Toolkit, but I wanted to flag it as a very helpful way to avoid re-writing types and as a goal for parse()
to make the exact attribute output evident for the TypeScript engine.
Perhaps in the meantime this typescript strategy could be included in the readme as it took me a while to figure out how to do this.
Thanks @famouspotatoes. I have been exploring ways to infer types from the entity definitions rather than requiring it separately. I will look into the redux stuff and see if there is anything I can use.
Nice 😀 Have you tried this with the library, @famouspotatoes? What is your result for this? It may "just work"...
@darbio I have and it works to the extent that it does not throw any typescript errors, but not to the degree of accuracy where typescript/IDE can infer the exact attributes and types.
I'm not sure how redux toolkit does it under the hood but i can say that it is very cool and makes this abstraction stuff a lot more effective.
Ah yes - I see. You have to have the method return T
. At the moment it returns:
// Return the entity
return Object.assign({
name,
schema: parseEntityAttributes(attributes,track), // removed nested attribute?
defaults: track.defaults,
required: track.required,
linked: track.linked,
autoExecute,
autoParse,
_etAlias: typeAlias
},
table ? { table } : {}
) // end mapping object
Making parseEntity
generic could make this work.
Does this already work for the generic constructor of entity? (Entity<T>
)
Hey @willsmanley, thanks for opening this issue and sorry for the delayed response.
This was added in v0.4, feel free to install the latest version of the library to get the TS inference.