Home > Back-end >  Advice on cleaning up copied typescript from a library
Advice on cleaning up copied typescript from a library

Time:07-19

This is a request for advice on best practices helping me understand what I'm doing.

I found the library react-google-calendar-api, npm installed it, and got it to work in my React project. I then decided I wanted to extend it (eg allow a user to see all their Google Calendars and use various CRUD calls on different calendars). I tried creating a separate file in my repo that imported the key class from the library (ApiCalendar) to try to write additional functions off of that, but that didn't work. (Question 0: should it have?)

So instead what I did is copy over the main file from the library into my own repo. After much futzing around (including installing typescript in my frontend React repo), I got to a point where the start of the file looked like this:

const scriptSrcGoogle = "https://accounts.google.com/gsi/client"
const scriptSrcGapi = "https://apis.google.com/js/api.js"


class ApiCalendar {
    tokenClient: google.accounts.oauth2.TokenClient | null = null;
    onl oadCallback: any = null;
    calendar: string = 'primary';
  
    constructor(public config: ConfigApiCalendar) {
...

This was throwing errors because it didn't recognize google (and also gapi, which appeared later in the file). My rough understanding is that google and gapi are defined in the scriptSrcGoogle and scriptSrcGapi defined at the top. So it should have worked.

And indeed it does as long as I tell Typescript to ignore the file, i.e. adding // @ts-nocheck to the top of the file makes everything work as if I was relying on the npm installed library.

To help deepen my understanding...

  1. Is this a fair way to 'extend' the library in a quick way? (I didn't want to clone the library and treat it as a library I created but would still have to npm install)
  2. Is there a better way to fix the problem with recognizing google and gapi aside from having Typescript ignore the whole file?

CodePudding user response:

Question 0: Without more context it is extremely difficult to troubleshoot your issue. In this situation you could likely extend behavior via inheritance.

import ApiCalendar from 'react-google-calendar-api';

class MyApiCalendar extends ApiCalendar {
  customMethod() {
    // do something
  }
};

let api = new MyApiCalendar(config);
api.customMethod(); 

Question 1: Copying and pasting code from a library should be avoided. See if you can add the behavior you want to your program by using the API provided by MyApiCalendar first. Personally I try to avoid inheritance if possible and instead try to extend behavior via composition. Can you use the ApiCalendar on its own to accomplish your task? What functionality needs is limited currently and needs changing? If the code that needs modification is internal to the class (e.g, an existing method), then you will likely need to resort to inheritance to override the specific method.

It's worth noting that TypeScript uses access modifiers (private, public, protected) to restrict what methods a subclass has access to. Your subclass will only have access to public or protected methods from the parent class. This is a TypeScript construct and not something which is enforced at runtime in JavaScript.

Question 2: Yes, you shouldn't have to turn off type-checking. If you want these globals to be defined in your own project (google/gapi), you will need to install the types like in react-google-calendar-api so that TypeScript knows what these objects are.

  • Related