An abstract class featuring a nested generic function that is also abstract

I am working on creating a dynamic table that can change its content and position based on a special row unique to each page.

Currently, I'm encountering an error

The generic type 'Table<SpecialFunctions>' requires 1 type argument(s).ts(2314)
when classes are extending the abstract Table class.

I have realized that in an abstract class, the child classes' getSpecialFunctions() method should return SpecialFunctions. How can I make this method return a specific type for each individual child class?


abstract class Table<SpecialFunctions> {
  constructor() {}

  loadData() {}
  showTable() {}
  updateCell() {}

  abstract getSpecialFunctions(): SpecialFunctions;
}

class DoneWorksPageTable extends Table {
  getSpecialFunctions(): TypeForSpecialRowOnDoneWorksPage{
    return {
      text: "test",
      addNewDoneWork: () => console.log("test done work class"),
    };
  }
}
class InformationPageTable extends Table {
  getSpecialFunctions(): TypeForSpecialRowOnInformationPage{
    return {
      toLoad: ["file", "table", "text", "image"],
      addNewInfo: () => console.log("test info class"),
    };
  }
}

Answer №1

The Table class you created is generic, with a type parameter called SpecialFunctions. This name functions as a placeholder in this context, similar to how parameters work in functions. The choice of name is up to you as the developer, as it only holds significance for you, not the compiler – which could easily use something like T instead.

Since the Table class mandates a type parameter, you must specify it whenever you use the class – much like providing arguments in a function call.

Therefore, you must indicate the necessary types when extending the class:

interface TypeForSpecialRowOnDoneWorksPage {}
interface TypeForSpecialRowOnInformationPage{}

abstract class Table<SpecialFunctions> {
  constructor() {}

  loadData() {}
  showTable() {}
  updateCell() {}

  abstract getSpecialFunctions(): SpecialFunctions;
}

class DoneWorksPageTable extends Table<TypeForSpecialRowOnDoneWorksPage> {
  getSpecialFunctions(): TypeForSpecialRowOnDoneWorksPage{
    return {
      text: "test",
      addNewDoneWork: () => console.log("test done work class"),
    };
  }
}
class InformationPageTable extends Table<TypeForSpecialRowOnInformationPage> {
  getSpecialFunctions(): TypeForSpecialRowOnInformationPage{
    return {
      toLoad: ["file", "table", "text", "image"],
      addNewInfo: () => console.log("test info class"),
    };
  }
}

Check out the live example on the TypeScript Playground here.

Answer №2

It seems that you have not provided the generics for your abstracts, as mentioned. The full error probably points to the lines where you are extending your tables. In essence, try this approach:

class DoneWorksPageTable extends Table<TypeForSpecialRowOnDoneWorksPage> {
  getSpecialFunctions(): TypeForSpecialRowOnDoneWorksPage{
    return {
      text: "test",
      addNewDoneWork: () => console.log("test done work class"),
    };
  }
}
class InformationPageTable extends Table<TypeForSpecialRowOnInformationPage> {
  getSpecialFunctions(): TypeForSpecialRowOnInformationPage{
    return {
      toLoad: ["file", "table", "text", "image"],
      addNewInfo: () => console.log("test info class"),
    };
  }
}

For reference: Playground Link

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

Using TypeScript in React, how can I implement automation to increment a number column in a datatable?

My goal is to achieve a simple task: displaying the row numbers on a column of a Primereact DataTable component. The issue is that the only apparent way to do this involves adding a data field with indexes, which can get disorganized when sorting is appli ...

Unexpected Issue: Angular 12 Encounters JIT Compiler Unavailability

Lately, I've been encountering a persistent issue with an error message: Uncaught Error: JIT compiler unavailable. Ever since I upgraded from Angular version 8 to 12, whenever I run the ng build --prod --output-path = dist command and build Angular, e ...

Unable to leverage vscode workspace path for the next js 13 project

I am facing an issue with TypeScript despite having the latest versions installed in my project (TypeScript 5.2.2 and @types/react 18.2.21): Next 13 — client and async server component combined: 'Promise<Element>' is not a valid JSX elem ...

When I attempt to return an object from a function and pass the reference to a prop, TypeScript throws an error. However, the error does not occur if the object is directly placed in

Currently, I have the following code block: const getDataForChart = () => { const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; const test = { ...

Angular: Utilizing httpClient to retrieve an object map and passing it as a return value in a function

I have a basic Angular application that retrieves data from a Spring-Boot backend. export class UserDto { constructor( public login: string, public password: string, ) { } } export class AuthService { private url = '....'; get ...

Alias route for `src` in Ionic 3

I have set up a custom webpack configuration for Ionic 3 in order to use src as a path alias (meaning I can import from src/module/file): resolve: { alias: { 'src': path.resolve('./src') } } However, after updating to Ionic ap ...

Looping through Observable with an Array using *ngFor in Angular

My Angular App is having trouble displaying all the items of a device due to issues with iterating through an observable array. The error message I am currently encountering is as follows: Error: Cannot find a differ supporting object '[object Obje ...

Navigate to a new tab using this.router.navigate

Is there a way to redirect the user to a specific page with ${id} opening in a new tab, after clicking a button in an angular material dialog box? I want to leave the dialog box open while querying the new page. Currently, the redirect happens but not in a ...

Ways to Conceal Information in Angular2

On my website, I have a layout with three tabs. In the third tab, I've implemented an ng-select tag. My goal is to only display the 1st ng-select tag initially, while keeping the other two hidden until the user selects data in the 1st tag. For referen ...

Ways to turn off Typescript alerts for return statements

I'm looking to turn off this Typescript warning, as I'm developing scripts that might include return values outside of a function body: https://i.stack.imgur.com/beEyl.png For a better example, check out my github gist The compiled script will ...

Locate the constructor for the class of the array element

I came up with a simple solution: function customFunction<T>(data:any, type:new(...args:any[])=>T):T{ //An illustrative example to point out the problem if(data instanceof Array){ return new type(); } return [new type()]; ...

Typescript narrowing facing difficulty in isolating property type

I encountered an issue with my code: interface Wide { prop: string | undefined } interface Narrow { prop: string } class Foo { prop: string constructor({ prop }: Narrow) { this.prop = prop } } const array = [{ prop: undefined }, { prop: &a ...

Tips for dynamically calling a property member of a function type in Typescript

How can I determine if a member is a function in TypeScript? Is dynamic typing discouraged in TypeScript? function checkIfFunction<T, K extends keyof T>(obj: T, propName: K) { if (typeof obj[propName] === "function") { obj[p ...

"Utilizing variadic tuple types to implement the pipe function in TypeScript 4: A step-by-step guide

An illustration from the release notes of TypeScript 4 demonstrates the use of variadic tuple types to eliminate multiple overload definitions. It seems feasible to type the pipe function for any number of arguments. type F<P, R> = (p: P) => R ty ...

The limitations of Typescript when using redux connect

Recently, I utilized TypeScript for React to declare a class with constraints and now I'm looking to implement the connect method. Here is the code snippet: import * as React from 'react'; import { connect } from 'react-redux'; im ...

Combining objects into an array of objects with matching keys

Seeking to combine objects with the same key within an array of objects. The initial object structure is as follows: const cultures = { "en-us": { "path": "/en/playground/copy/", "startItem": { ...

Angular2 and TypeScript bug "The property METHOD_NAME is not found on the type 'typeof CLASS_NAME'"

Seeking assistance with Angular2 and TypeScript as I transition from A1 to A2. Currently, I am facing a situation that may seem obvious for experienced developers: Here's the scenario: Utilizing Webpack. AppConfigConst contains static, app-wide con ...

Setting up grunt-ts to function seamlessly with LiveReload

I am currently experimenting with using TypeScript within a Yeoman and Grunt setup. I've been utilizing a Grunt plugin called grunt-ts to compile my TypeScript files, and while the compilation process is smooth, I'm encountering issues with live ...

Function type cannot be restricted by type guards

I have a function that takes in parameters with similar structure and uses type guards internally to determine the type of parameter being passed. type Example1 = { data: 'data', param1: 'yes' } type Example2 = { data: 'data ...

Using Ionic to send HTTP requests with authentication headers

I'm encountering an issue with Ionic where it insists on sending a pre-fetch request to the server without a JWT token, causing the app to crash. Additionally, I need a way to capture non-200 responses from the server as it frequently returns errors l ...