Amgg
Amgg

Reputation: 117

Type sharing between frontend and backend without bundling the ORM

In a fullstack typescript project i wish to share the interface/types that i use on the backend project in the frontend project to avoid code duplication and keep consistency.

From search i found that this can be done by having a third "shared" project with these types and then using typescript's referenced projects to include it.

So i would have a Frontend project, Backend project and a Shared project that would be referenced by the first two.

Although my types extend the mongoose's Document type, witch would cause the need for mongoose to be bundled in the frontend project in order to use the same types in both the frontend and backend.

What is the proper way to share these interfaces/types without bundling the extra backend packages to the frontend? (and keeping the _id property that comes from the Document extension as well while we are at it).

RoadBook.ts (IRoadBook is the interface/type to be shared and mongoose schema,model declaration)

import mongoose, {Schema,Model,Document} from 'mongoose';

export interface IRoadBook extends Document {
    Name  : string;
    Description : string;
}

const RoadBookSchema = new Schema({
    Name : {type : String, required : true, unique: true},
    Description : {type : String }
});

export default mongoose.model<IRoadBook>('RoadBook',RoadBookSchema);

Might be important to reference that the backend is a simple typescript/express/mongoose app and the frontend a react webapp.

Thank you in advance.

Upvotes: 4

Views: 2887

Answers (1)

dx_over_dt
dx_over_dt

Reputation: 14318

What you could do is define the IRoadBook interface in your ORM which doesn't extend Document except for the members that you need in both the front end and the back end. Then, in the back end, define the schema.

ORM

export interface IRoadBook {
    _id: string; // or ObjectID or whatever type mongoose.Document['_id'] is
    Name: string;
    Description: string;
}

Back end

import mongoose, { Schema, Model, Document } from 'mongoose';
import { IRoadBook } from 'my-orm';

const RoadBookSchema = new Schema({
    Name: { type: String, required: true, unique: true },
    Description: { type: String }
});

export default mongoose.model<IRoadBook & Document>('RoadBook', RoadBookSchema);

Upvotes: 2

Related Questions