Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share types between client and server

I'm working on a project with a Node.js, Express.js & TypeScript backend (REST API) and a React, Redux & TypeScript frontend.

In the backend I have created some types for example:

models/Product.ts

export type Product = {
    title: string
    description: string
    price: number
}

So the REST API is sending a response like the following:

{
  "data": [
     {"title": "Shoe", "Description": "This is a shoe.", "price": 20},
     {...}
   ] // inside here all the Products[]
}

On the client I want to cast the data to the type Product array. But since the frontend and backend are different code bases and separated, I still want to take the advantage of using types on the frontend. But I want to achieve this without duplicating code. So I don't want to update 2 places when modifying or adding models.

Does someone know what is the best way to share types between client and server?

I was thinking of something like creating an endpoint on the backend which the client can hit, then it writes all the models in a single file for example models.ts on the client. So I think I need to loop through every file inside /models/ on the backend then parsing it in a new file which is written on the client as models.ts. But is this really a good way? Does someone know a better way of achieving this structure?

like image 909
Steven Soekha Avatar asked Nov 27 '20 23:11

Steven Soekha


People also ask

Where are shared types TypeScript stored?

if you use a type/interface in more than one place it goes into the ~shared/lib/types. ts file. if you have a component that's used in more than one place it gets refactored to to the ~shared/components folder. if you extend a type/interface, it can be declared locally, but as long as it doesn't get used more than once.


1 Answers

You can use TypeScript path mapping.

Example from a project I'm the author of:
Backend defined types inside SampleTypes.ts are reused in the client project to avoid duplicating the code.

client/tsconfig.json:

{
  "compilerOptions": {
    "paths": { "@backend/*": ["../server/src/api/*"], },
  }
}

../server/src/api/ -> https://github.com/winwiz1/crisp-react/tree/master/server/src/api

client/....ts:

import { SampleRequest } from "@backend/types/SampleTypes";
like image 56
winwiz1 Avatar answered Sep 29 '22 11:09

winwiz1