Is it possible to define a unique function signature in a child class when implementing a method from a parent class?

In the process of developing a repository module that includes generic methods, I have found that as long as each derived class has the `tableName` configured, the basic query for creating, finding, or deleting records remains consistent across all child classes.

Although I have made an attempt at this (outlined below), the TypeScript compiler is raising an error:

Type 'Car' is not assignable to type 'T'.
  'T' could be instantiated with an arbitrary type which could be unrelated to 'Car'.

Consider the following example:

// Inside base-repo.ts
class BaseRepo {
  static create<T>(columns, values): T {
    // This is just a simplified example - the actual implementation is more robust
    return db.execute(`INSERT INTO ${this.tableName} (${columns}) VALUES (${values})`)
  }
}

// In car-repo.ts
interface Car {
  id: number
  make: string
  model: string
}

class CarRepo extends BaseRepo {
  static get tableName() {
    return 'cars'
  }
}

// In another file
// The goal is to automatically infer the type as `Car` based on configuration in `car-repo.ts`
const carRecord = CarRepo.create(..., ...)

// ----------------------------

// This approach does not work and results in the aforementioned error:
class CarRepo extends BaseRepo {
  static create(columns, values): Car {
    return BaseRepo.create<Car>(columns, values)
  }
}

// This alternative solution works but is less than ideal
class BaseRepo {
  static createRecord<T>(columns, values): T {}
}

class CarManufacturer extends BaseRepo {
  static create(columns, values): Car {
    return this.createRecord<Car>(columns, values)
  }
}

It seems like the issue may lie in attempting to overwrite a parent method while the type signatures are not completely compatible.

Answer №1

Here is an example of what you might use:

public class VehicleRepository extends BaseRepository<Vehicle> {
  // Add your code here
}

Answer №2

Avoid using inheritance in this scenario as it does not adhere to the Liskov substitution principle. A more suitable approach would be to utilize a simple function like the one below:

function insertData<T>(tableName: string, columns: any, values: any): T {
  return db.execute(`INSERT INTO ${tableName} (${columns}) VALUES (${values})`);
}

function insertCar(columns: any, value: any): Car {
  return insertData('cars', columns, value);
}

If you prefer working with class + static method, although it may not add much value:

class BaseRepository {
  static insertData<T>(tableName: string, columns: any, values: any): T {
    return db.execute(`INSERT INTO ${tableName} (${columns}) VALUES (${values})`)
  }
}

class CarRepository {
  static readonly tableName = 'cars';
  static insert(columns: any, values: any): Car {
    return BaseRepository.insertData(CarRepository.tableName, columns, values);
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to identify errors in an express listen callback function?

My current code is set up to verify if there was an error while initiating Express: express() .listen(port, (err: Error) => { if (err) { console.error(err); return; } console.log(`Express started`); ...

Error TS2532 in TypeScript indicates that there is a possibility that the object is undefined

Yesterday, WebStorm 2020.1 was installed on my computer. All of a sudden, I started encountering numerous TS2532 errors. How is it even possible for this to be "undefined"? Doesn't selectedOwner && prevent that? I attempted to eliminate thi ...

What steps should I take to fix this Angular 8 error?

Encountered an issue in ../node_modules/@angular/http/src/backends/jsonp_backend.d.ts:1:28 - error TS2307: Module 'rxjs/Observable' not found. 1 import { Observable } from 'rxjs/Observable'; ~~~~~~~~~ ...

What is the most effective method for designing a scalable menu?

What is the most effective way to create a menu similar to the examples in the attached photos? I attempted to achieve this using the following code: const [firstParentActive, setFirstParentActive] = useState(false) // my approach was to use useState for ...

Maintain Angular Dropdown Menu Open Across Page Refresh

I am currently working on an HTML/Typescript view that is connected to a SQL Database. Whenever there are changes made to the database, the entire webpage reloads. The issue we are facing is that we have dropdown menus on the page that clients want to rema ...

How do I manage 'for' loops in TypeScript while using the 'import * as' syntax?

When working with TypeScript, I encountered an issue while trying to import and iterate over all modules from a file. The compiler throws an error at build time. Can anyone help me figure out the correct settings or syntax to resolve this? import * as depe ...

Sinon fails to mock the provided URL when GET request includes parameters

I am currently working on creating test cases for the services in my Angular application and encountering some challenges. Below is the code snippet for the service: /** * Sends http request to fetch client states and territories available for a specifi ...

What is the best way to bring a local package into another npm package and verify its functionality using Typescript?

In a scenario where there are 3 npm projects utilizing Webpack and Typescript, the folder structure looks like this: ├── project1/ │ ├── tsconfig.json │ ├── package.json │ ├── src/ │ │ └── index.ts │ ...

Display a modal dialog using HttpInterceptor

@Injectable() export class MyInterceptor implements HttpInterceptor { intercept(req : HttpRequest<any>, next : HttpHandler) : Observable<HttpEvent<any>> { //display a modal dialog to wait for user response before proceeding with t ...

The error message "Uncaught TypeError: emit is not a function in Vue 3" indicates

As I implemented the code in the Vue 3 setup block to retrieve the input value according to this answer, here is a snippet of the code: import { defineComponent } from "vue"; import { defineProps, defineEmits } from 'vue' export defaul ...

typescript: textual depiction of a generic type T

I have a requirement to develop a method that is capable of handling generic data types, and I need to incorporate the type information into the method Our API requires passing the entity name as a parameter: http://server/api/fetch/Entity/123 It's ...

Add a feature to a functional component that is enclosed with React.forwardRef

Within my codebase, there exists a component that is wrapped with React.forwardRef and serves as a compound component. One challenge I encountered was how to preserve the functionality of Form.Item = FormItem; while still having the Form component fun ...

Encountering issues with @typescript-eslint/typescript-estree due to using a non-officially supported version of TypeScript after updating Nuxt

After upgrading Nuxt in my project using the command npx nuxi upgrade, I encountered an issue while running eslint .. The output displayed a warning regarding the TypeScript version: ============= WARNING: You are currently running a version of TypeScript ...

Differentiating response.data typing on the front end in Typescript depending on the request's success status

Consider this scenario: A secure API authentication route that I am not allowed to access for viewing or editing the code returns interface AuthSuccess { token: string user: object } on response.data if the email and password provided are correct, but ...

How to leverage tsconfig paths in Angular libraries?

While developing an Angular library, I made configurations in the tsconfig.lib.json file by adding the following setup for paths: "compilerOptions": { "outDir": "../../out-tsc/lib", "target": "es2015", "declaration": true, "inlineSources ...

A guide to sending epoch time data to a backend API using the owl-date-module in Angular

I have integrated the owl-date-time module into my application to collect date-time parameters in two separate fields. However, I am encountering an issue where the value is being returned in a list format with an extra null value in the payload. Additiona ...

Error encountered numerous times within computed signals (angular)

I have incorporated signals into my Angular application. One of the signals I am using is a computed signal, in which I deliberately introduce an exception to see how it is handled. Please note that my actual code is more intricate than this example. pu ...

Tips for inputting transition properties in Material UI Popper

Currently, I am making use of material ui popper and I would like to extract the transition into a separate function as illustrated below: import React from 'react'; import { makeStyles, Theme, createStyles } from '@material-ui/core/styles& ...

Sequelize is not giving the expected model even after utilizing `include: [{ model: this.buildModel, required: true }]`

I've hit a roadblock trying to solve this problem. Despite my belief that I've correctly handled the migration, model definition, and query, I'm unable to retrieve the build in my iteration. Below are the models: SequelizeBuildModel.ts @Ta ...

Troubleshooting: Difficulty with Angular 2 TypeScript interface array functionality

Currently, I am developing an Angular 2 application where I aim to showcase messages by utilizing an interface and storing all the messages in an array. Below is a snippet of my TypeScript component that highlights this functionality: export class ChatCom ...