Creating entities that have required properties with default values in TypeScript
Maher4Ever opened this issue · comments
Hello,
Consider the following definition of a User
entity:
interface UserType {
name: string;
status: string;
}
type UserEntity = Entity<UserType>
const schema = new Schema<UserType>({
name: {
type: String
},
status: {
type: String,
values: ['unverified', 'verified'],
default: 'unverified',
write: false,
required: true
},
})
const User = gstore.model('User', schema)
If you now try to create a user without passing a status
then the compiler complains:
const user = new User({ name: 'John' })
/*
Argument of type '{ name: string; }' is not assignable to parameter of type 'EntityData<UserType>'.
Property 'status' is missing in type '{ name: string; }' but required in type 'EntityData<UserType>'.ts(2345)
*/
According to the documentation this can be solved by making the status
property optional in the interface:
interface UserType {
name: string;
status?: string;
}
const user = new User({ name: 'John' }) // OK
However, now I'm forced to tell the compiler everywhere the status
property is used that it can't be undefined
:
const status: string = user.status // Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.ts(2322)
// The following works of course but it's annoying
const status: string = user.status!
Is there a better way to handle this use case?
Hello,
As far as I know, this is how it should be. If you create a user with
const user = new User({ name: 'John' })
That user does not have a status
, it this then undefined
. If your logic updates the status, you are the only one that knows it for sure and that's why Typescript lets you add an !
behind.
I can see that. Would it be possible to add a factory method to models that takes a Partial
entity type?