Using Typescript: Utilizing generic types within the parent class

I'm currently facing an issue with the code snippet below, which is a simplified example:

class QueryArgs {
  studentId?: string;
  teacherId?: string;
}

class BaseValidator<T> {
  protected args: T;

  constructor(args: T) {
    this.args = args;
  }

  protected requireTeacher(): void {
    if (!this.args.teacherId) {
      throw new Error("teacherId required");
    }
  }
}

class QueryValidator extends BaseValidator<QueryArgs> {
  public validateAdmin(): QueryArgs {
    this.requireTeacher();
    return this.args;
  }
}

// Sample implementation mimicking a third-party library
const args: QueryArgs = new QueryArgs();
args.studentId = "XXXX-XXX-XXX";

// Just for demonstration purposes, not actual implementation
const validator = new QueryValidator(args);
const validArgs = validator.validateAdmin();

The error I encounter lies within the BaseValidator class and specifically in the requireTeacher method where this.args.teacherId triggers the message

Property 'teacherId' does not exist on type 'T'
.

I can't seem to figure out what I am overlooking in terms of TypeScript generics.

In an ideal scenario, TypeScript should recognize that in the BaseValidator, the args object is an instance of QueryArgs.

Any help or insights would be greatly appreciated. Thank you!

Answer №1

In order to ensure that the generic type argument T has a teacherId property, you need to add a constraint. Currently, any type can be passed as T, making it impossible to assume that T includes teacherId.

To enforce this constraint, consider updating class BaseValidator<T> to

class BaseValidator<T extends QueryArgs>
. By doing so, you limit T to types that extend QueryArgs, guaranteeing the presence of a teacherId property within T.

For more information on constraining generic arguments using extends, refer to this article: https://www.typescriptlang.org/docs/handbook/generics.html

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

Deduce the generic types of conditional return based on object property

My goal is to determine the generic type of Model for each property. Currently, everything is displaying as unknown[] instead of the desired types outlined in the comments below. playground class Model<T> { x?: T } type ArgumentType<T> = T ...

React and TypeScript warns about possible undefined object

certificate?: any; <S.Contents>{certificate[0]}</S.Contents> <S.Contents>{certificate[1]}</S.Contents> <S.Contents>{certificate[3]}</S.Contents> If I set the type of props to `any` and use it as an index of an array, e ...

Invoke the API when the value of a property in the SPFX property pane is modified

Here's a question that might sound silly, but I'll ask anyway. I have a dropdown field in my Property pane that is filled with all the lists from the current site. It's working fine. When I change the dropdown selection, it populates a pro ...

Looking for a way to validate all form fields even when only one field is being used?

In Angular 8, I am facing an issue where the current validation only checks the field being modified. However, there are some fields whose validation depends on the values of other fields. Is there a way to make Angular recheck all fields for validation? ...

Encountering a compilation error when implementing ActionReducerMap in combination with StoreModule.forFeature

In my Angular project, the structure is organized as follows: /(root or repo folder) |_ projects |_ mylib (main library to be exported from the repo) |_ sample-app (created for testing 'mylib' project in other projects) To manage appli ...

What is the best practice for Angular: running production build before or after testing?

When developing a Java application for production, I typically set up the build process to create the production artifacts first and then run tests against those artifacts. Recently, I joined an Angular project and noticed that the build process is struct ...

Is it compatible to use Typescript version 2.4.2 with Ionic version 3.8.0?

Is it compatible to use Typescript 2.4.2 with Ionic 3.8.0? $ ionic info cli packages: (C:***\AppData\Roaming\npm\node_modules) @ionic/cli-utils : 1.18.0 ionic (Ionic CLI) : 3.18.0 global packages: cordova (Cordova CLI) : not insta ...

The use of props within components is broken in the interface of Nuxt and Vuejs

I am having trouble accessing an object's interface within a component using props. Is there anyone who can provide guidance on how to resolve this issue? PortariaInterface define interface PortariaInterface { entryDate: string nfe?: { numbe ...

react-vimeo not firing onPause and onPlay events

I am facing an issue with triggering props when playing a Vimeo video on my webpage. Here's a snippet of my code: import Vimeo from '@u-wave/react-vimeo'; const handleVimeoProgress = (data: any) => { console.log('Progress:' ...

Is there a way to fetch a particular object from Firebase database based on its value using AngularFire2?

Here is the database I am working with: firebase database I am trying to retrieve a dish that has its 'featured' attribute set to true (dish.feature = true). Is it possible to do this directly from the database, or do I have to retrieve all di ...

Advanced TypeScript deduction

I have a coding query: interface Feline{ purr:boolean } interface Jungle{ lion:Feline, tiger:Feline, leopard:Feline } later in the code: let cats:Jungle;// assume it's properly defined elsewhere for(const j in cats) if(cats.hasOwnProperty(j)){ ...

What is the process for moving information between files?

I have two files which are named as, employee-rates-controller.ts: private load() { return this.entityService .load(this.$scope.projectRevisionUid) .then(resp => { localStorage.removeItem('employeerates'); this.$ ...

What could be the reason behind the error related to react-router-dom?

index.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.S ...

The functionality to disable the ES lint max length rule is malfunctioning

In trying to disable an eslint rule in a TypeScript file, I encountered an issue with a regular expression that exceeded 500 characters. As a result, an eslint warning was generated. To address this, I attempted to add an eslint comment before declaring th ...

What is the method for extracting the types of parameters from a function type while excluding a single parameter?

Suppose I have the following interface that defines a function: export declare interface NavigationGuard { (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext): NavigationGuardReturn | Promise<NavigationGuardReturn ...

Troub3leshooting Circular Dependency with Typescript, CommonJS & Browserify

I am currently in the process of transitioning a rather substantial TypeScript project from internal modules to external modules. The main reason behind this move is to establish a single core bundle that has the capability to load additional bundles if an ...

How can I retrieve the row index in an Angular Mat-Table that has expandable content?

Having a mat-table with expandable content on a page, I am seeking a solution to record the row number of the table when clicked. While I successfully achieved this with a regular table in the HTML file using: <tr mat-row *matRowDef="let row; columns: ...

Locate a user within an array in Angular 5 by inputting a specific character into a textarea before initiating the search

I'm currently facing a situation with my textarea component... <textarea [(ngModel)]="message" id="commentBox" placeholder="Add your comment here..."></textarea> Additionally, I have a user list that retrieves data from an external API l ...

Encountering an issue with importing typeDefs in Apollo Server (Typescript) from an external file

I decided to move the typeDefs into a separate file written in typescript and then compiled into another file. Upon doing so, I encountered the following error: node:internal/errors:490 ErrorCaptureStackTrace(err); ^ Error [ERR_MODULE_NOT_FOUND]: Una ...

Effortless code formatting with VS Code for TypeScript and JavaScript

Does anyone know of any extensions or JSON settings that can help me format my code like this: if(true) { } else { } Instead of like this: if(true){ } else { } ...