I'm trying to figure out how to implement my User class since the database generates the user IDs. My issue is what to pass to the `function createUser(user: User)` because if the ID is a `private readonly` field in the User class, I can't create a User instance until it gets an ID from the database. I've thought of a few approaches: 1) Making the `id?` field optional, which means I'll have to check if it's defined everywhere; 2) Using a union type `number | undefined` and creating static methods like `create` (for initial creation) and `fromDatabase` (after fetching from the database), but that dilutes the definition of my User object; 3) Creating a UserDTO class without strict id requirements, which doubles the number of entity files. I'm hoping to get some feedback on the best way to handle this without resorting to an ORM, as I'm trying to improve my SQL skills. What do you all think?
8 Answers
I suggest focusing on the basic user details like username or email and password. Hash the password, create a record in your database, and then return the new record including the auto-generated ID.
You could use a UUID, nanoId, or a snowflake ID generator inside the `createUser` function, which would eliminate the need to handle IDs from the database.
You might consider defining a type like `NotAUserYet = Omit` and using that in your `createUser` method.
If `createUser` is the first method you run when a visitor interacts, do you really need to pass a user object? Maybe just have `createUser()` that generates and throws an error if the database call fails.
I'd advise against making the ID optional in your User class. Instead, consider using a Partial type for scenarios where the user isn't created yet, but keep that to a minimum to avoid issues later on.
It seems like you're caught between needing a user object and not being able to create one without an ID. I'd suggest separating the creation interface from the finalized User interface. For example:
```typescript
type CreateUserPayload = { name: string, password: string }
type User = { id: string, name: string }
function createUser(user: CreateUserPayload): User {
const result = db.insert(user);
return {
id: result.id,
name: result.name,
};
}
```
Make sure that when you're setting up your user table, you set the ID field to auto-increment. This way, you won't need to worry about the ID at all during user creation; the database will manage it.
You could also write it like this:): User {
```typescript
function createUser(user: Omit
```