Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I define interfaces of documents when using Typescript and Mongodb?

Consider a simple user collection:

// db.ts
export interface User {
      _id: mongodb.ObjectId;
      username: string;
      password: string;
      somethingElse: string;
}

// user.ts
import {User} from "../db"
router.get("/:id", async (req, res) => {
    const id = req.params.id;
    // user._id is a mongodb.Object.
    const user: User = await db.getUser(id);

    res.send(user);
});

// index.ts
// code that will runs on browser
import {User} from "../../db"
$.get('/user/...').done((user: User) => {
    // user._id is string.
    console.log(user._id);
});

It works perfectly until I want to use this interface in client codes. Because the _id of user becomes a hex string when tranmitted as json from server. If I set _id to be mongodb.ObjectId | string, the behavior gets wierd. enter image description here

like image 898
Zen Avatar asked May 11 '16 09:05

Zen


2 Answers

You can try to separate them in a smart way :

interface User {
   username: string;
   password: string;
   somethingElse: string;
}

export interface UserJSON extends User {
   _id : string
}

export interface UserDB extends User {
   _id : mongodb.ObjectId
}

and later take either UserJSON ( client ) or UserDB ( server-side ).

like image 64
drinchev Avatar answered Nov 08 '22 00:11

drinchev


Thanks to @drinchev. And I have figured out a better way to do it, using generics:

interface User<IdType> {
    _id: IdType;
    username: string;
    posts: Post<IdType>[];
}

interface Post<IdType> {
    _id: IdType;
    text: string;
}

export type UserDB = User<mongodb.ObjectID>;
like image 2
Zen Avatar answered Nov 08 '22 00:11

Zen