You cannot use the term "prototype" to reference a class type

As per the documentation of Typescript, the correct type for defining a class constructor is as follows:

type Class = { new (...args: any[]): {} }

If you try to access this type like this:

type ClassPrototype = { new (...args: any[]): {} }["prototype"]
// OR
type ClassPrototype = Class["prototype"]

The compiler will not show any errors in the above cases. However, when attempting the following code, an error occurs:

type PrototypeOf<T extends { new (...args: any[]): {} }> = T["prototype"] // <-- Type '"prototype"' cannot be used to index type 'T'.

The reason behind this behavior is unclear. If indexing Class with Class["prototype"] works fine, then why does it fail when using generics like <T extends Class> and T["prototype"]? As a temporary workaround, replacing <T extends Class> with <T extends { prototype }> seems to resolve the issue but doesn't seem very clean.

To see how this context plays out, check out this playground link.

Answer №1

When it comes to a class constructor, the prototype property holds a type that represents the class itself.

Let's break it down with an example:

class Class {
  methodA(): void {}
}
const a: Class = Class.prototype // works fine
type Test = Class['prototype'] // throws an error

In this scenario, invoking the Class (constructor) with new results in a value of type Class (an instance).

It's interesting how TypeScript allows runtime access of Class.prototype but not the type of Class['prototype']. This could be a deliberate choice to simplify working with classes, even though it makes dealing with prototypical patterns tougher since classes are more prevalent in modern codebases.

If the type Class['prototype'] doesn't function as expected on a real class, then it's unlikely to exist on an abstract class constructor type either.


If you're looking for an alternative, you might want to consider using InstanceType<T> instead.

type ClassConstructor = { new (...args: any[]): ClassInstance }
type ClassInstance = { methodA(): void }

type A = ClassConstructor['prototype'] // type is any, so not particularly useful
type B = InstanceType<ClassConstructor> // type is ClassInstance
type C = InstanceType<ClassConstructor>['methodA'] // type is void

Explore further in the Playground

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

The error message is: "Cannot access property 'up' of an undefined object within the material UI library using theme.breakpoints."

I am encountering difficulties with the export of makeStyles. Below you can find my code and configuration: import SearchField from "../SearchField"; import { TextField, Select, useMediaQuery, Grid, Button, Box, Fade } from '@material-ui/core&ap ...

Implementing Service Communication

I created an Angular Application using the Visual Studio Template. The structure of the application is as follows: /Clientapp ./app/app.module.shared.ts ./app/app.module.client.ts ./app/app.module.server.ts ./components/* ./services/person-data.service. ...

How is it possible that there is no type error when utilizing copy with spread syntax?

When I use the map function to make a copy of an array of objects, why doesn't it throw an error when adding a new property "xxx"? This new property "xxx" is not declared in the interface. interface A{ a:number; b:string; }; let originalArray:A[] ...

Why did the compilation of Next.js using TypeScript and ESLint succeed despite encountering errors?

I've been delving into Next.js and encountered unexpected results when integrating TypeScript and ESLint. ESLint seems to work well with TypeScript, but my project compilation is successful despite encountering errors. It's puzzling why the comp ...

Encountering authorization issues while using CASL in conjunction with PrismaORM, NestJs, and Typescript results in an

Within a middleware, I am implementing a condition to grant access to users who reside in the same apartment as the authenticated user. The condition is as follows: can(DirectoryAction.VIEW, 'DirectoryUser', { roles: { some: { role: { unitId: CAS ...

Make sure to pass refs when using FC children with Next.js Links

I am struggling to understand the documentation in next.js regarding passing refs to children functional components. It's confusing to me and I'm finding it difficult to implement. For example, let's consider a functional component that dis ...

FInding the inner value of a Vuetify chip

I have a Vue application that utilizes Vuetify chips to display information. I'm trying to log the value inside a specific chip when it is clicked, but I keep getting an undefined error when trying to access the array where the information comes from. ...

Tips for displaying validation error messages in an Angular form

I need help displaying a validation error message for an Angular form. I have three checkboxes and I want to show an error message if none of them are selected. Can anyone provide guidance on how to implement reactive form validation in Angular? Here is a ...

Display a caution when verifying a function's value instead of its return value

I've encountered a common pitfall (especially with autocomplete) while testing a function return value. There are instances when I forget to include the parentheses () at the end, causing it to always return true. class Foo { public bar(): boolea ...

Using TypeScript to assign string array values to object properties

I am working with a string array: values: string['myName', 'myLastname', 'myAge'] and my goal is to assign each value to a property of an object like this: myModel={name:'', lastname:'', age:''} o ...

What is causing TypeScript to compile and remove local variables in my Angular base controller?

I am trying to develop a base controller in Typescript/Angular for accessing form data, but I'm encountering an issue where the form member seems to be getting removed during compilation and is not present in the generated JavaScript code. Could you ...

Is it feasible to conditionally set a function parameter as optional?

type TestType<A> = [A] extends [never] ? void : A class Singleton<T, A> { private ClassRef: (new (...args: A[]) => T) private args: TestType<A> private _instance?: T constructor(ClassRef: (new (...args: A[]) => T), ...

After installing Angular 10, warnings about optimization for rxjs and lodash CommonJS or AMD dependencies may be displayed

After successfully upgrading my application from Angular 9 to Angular 10, I encountered some warnings when running the ng serve command. WARNING in src\app\auth\guard\auth.guard.ts depends on 'lodash'. CommonJS or AMD dependen ...

Struggling to determine the type of constant after a specific type check? (TS2349: Unable to call a function on a type that does not have a call signature

Encountered a puzzling issue with TypeScript where it appears that I should be able to recognize that a constant is an array, and then utilize array methods on it. However, TypeScript seems unable to confirm that a value is truly an array even after a dire ...

angular2 with selenium webdriver: Issue with resolving 'child_process' conflict

I followed these steps: ng new typescript-selenium-example npm install selenium-webdriver --save I also made sure to copy chromedriver to my /Application. I updated the app.component.ts file as shown below: import { Component } from '@angular/core ...

The art of blending different inheritance (Styled Elements)

Can components be based on other styled components? Take a look at the code snippets below. I am interested in creating a component like this: const HeaderDropDownLi = styled(DropDownLi, HeaderItem) Both DropDownLi and HeaderItem are derived from a style ...

Having trouble executing the typescript build task: Command 'C:Program' is not valid as an internal or external command

I'm currently working on converting typescript code to JavaScript and have been following the steps outlined in the documentation. To automate the compilation of .ts files, I set up a watch task triggered by pressing Ctrl+Shift+B. However, upon runni ...

Steer clear of unauthorized value updates to a Python class attribute

Consider the following scenario: there is a class that requires attribute x to be either an integer or a float: class bar(object): def __init__(self, x): if not isinstance(x, float) and not isinstance(x, int): raise TypeError(&apos ...

I would like to modify the text color of a disabled input field

I need to adjust the font color of V1, which is a disabled input field. I want to make it darker specifically for Chrome. Any suggestions on how I can achieve this? https://i.sstatic.net/kioAZ.png Here's my HTML code: <mat-form-field appearance= ...

Experiencing a freeze in WebStorm 11 when trying to navigate to the declaration of Typescript interfaces

As I work on a massive NodeJS/Typescript project in WebStorm 11, I frequently experience complete freezing when using the "Go To -> Declaration" shortcut. This forces me to manually kill and restart WebStorm. Have any of you experienced this issue as w ...