Repository navigation
Access base class protected methods in static block #62738
Description
Activity
Btw the compiler suggestions to use the derived type is also misleading as it does not have the same runtime behaviour:
Property 'myMethod' is protected and only accessible through an instance of class 'MyDerivedClass'. This is an instance of class 'MyClass'.(2446)For me this sounds like I could do the same using 'MyDerivedClass' but this would end up in an infinite recursive call
Your example is a bit weird.
// not allowed ts2339is a typo, right? You meants2349? But that's just because you left out a semicolon and you relied on ASI to insert it, and it didn't. Put in the semicolon and you get an actual error you're presumably trying to talk about,ts2446.And the error on
superis a good one. If you run that code using any runtime that supports static blocks you'll get an error likeuse of super property accesses only valid within methods or eval code within methods. You want TS to issue an error there because you're trying to avoid a runtime error.Maybe you could edit your examples (and include them as plaintext) to focus on the issue you're facing?
Here the example in plain text:
class MyClass { protected myMethod() { // ...some logic } } class MyDerivedClass extends MyClass{ protected override myMethod() { // ... some additional logic super.myMethod() } static { this.prototype.myMethod = function(this: MyDerivedClass) { // ... some additional logic super.myMethod() // super undeclared ts2660 MyClass.prototype.myMethod.call(this); // not allowed ts2446 (MyClass.prototype as any).myMethod.call(this) // This works but is unsafe (MyClass.prototype as MyDerivedClass).myMethod.call(this) // This works but is unsafe } } }
However I found an 'elegant' solution I guess:
class MyDerivedClass extends MyClass{ protected override myMethod() { // ... some additional logic super.myMethod() } static { const base = this.prototype.myMethod; this.prototype.myMethod = function(this: MyDerivedClass) { // ... some additional logic base.call(this); } } }
This is I think the correct solution anyway because it properly infers the types and also also does not need direct access to the base type. So maybe it is fine as is, did not think about that I could just store the existing method as a temp variable.
RyanCavanaugh commented
on Nov 10, 2025 MemberMore actions🤖 Thank you for your issue! I've done some analysis to help get you started. This response is automatically generated; feel free to 👍 or 👎 this comment according to its usefulness.
Similar Issues
Here are the most similar issues I found
- (68%) microsoft/typescript#7492: Support super calls in static functions
- (67%) microsoft/typescript#4038: Feature suggestion: treat prototype assignments like merging type declarations
- (66%) microsoft/typescript#42215: 'super.prop' in static method should be allowed to access static properties of base class
- (66%) microsoft/typescript#56245: Allow anonymous/dynamic override / implementation of method without the need for a declared subclass
- (66%) microsoft/typescript#30537: Allow "this.constructor" in a constructor before super
- (65%) microsoft/typescript#613: Proposal to remove inheritance of static properties
If your issue is a duplicate of one of these, feel free to close this issue. Otherwise, no action is needed.
RyanCavanaugh commented
on Nov 11, 2025 MemberMore actionsThis specific error seems wrong
MyClass.prototype.myMethod.call(this); // not allowed ts2446
- addedBugA bug in TypeScriptA bug in TypeScriptHelp WantedYou can do thisYou can do this
on Nov 11, 2025 Andarist commented
on Nov 12, 2025 ContributorMore actionsThis error message ain't the best either:
class OtherClass { protected myMethod() {} } class OtherDerivedClass extends OtherClass { someMethod(a: OtherClass) { // Property 'myMethod' is protected and only accessible through an instance of class 'OtherDerivedClass'. This is an instance of class 'OtherClass'.(2446) a.myMethod(); } }
The mention of
OtherDerivedClassin the context of this error message feels confusing.- added a commit that references this issue
on Nov 13, 2025 - addedDomain: classesBehavior of various `class` constructs, e.g. mixins or base classesBehavior of various `class` constructs, e.g. mixins or base classes
on Nov 18, 2025
🔍 Search Terms
✅ Viability Checklist
⭐ Suggestion
Hey there, I have a use case where I want to declare/override a protected method using it's prototype.
With the addition of static blocks I can now override the method itself, however I can't call the same method of the base class using super. This makes it impossible to create dynamic overrides of a prototype method atm.
My suggestion would be to allow the usage of the base type prototypes in a static block of the class as well.
This would make it a lot easier to dynamically override/declare a method without using instance fields.
📃 Motivating Example
TypeScript now supports dynamic method overrides using static initialization blocks instead of runtime checks.
💻 Use Cases
1. What do you want to use this for?
Dynamic method declarations / overrides
Dynamic class creation using an options object.
2. What shortcomings exist with current approaches?
Currently the only way I see to do this is either:
3. What workarounds are you using in the meantime?
Example:
https://www.typescriptlang.org/play/?ssl=25&ssc=2&pln=1&pc=1#code/MYGwhgzhAECyCeBhcVoG8BQ1oAcBOA9gC4CmwpAJtALbywlEAWBFAFAJTpbbQD0v0AHTCIBaiWggCAcwCWwbgF8MyjKEgwEAERJ5ZANxIVkG6CQAepAHYVNSFBEzZ8xMpWgFDePRQm16TCwcXDx8AsKC0KLi0GAUFLJEsgRWYCCSMvLc2BAArji6gv4MzGzsShjcEERgScAhPEyyEIIuRMTwBUV0JSzQALzQAGa5VuTJVqxNEABccPA6eobGDpxOoWFCwlFiEnEJSSlpGXIK2Tx5BXjdAaXB-FH5utCjvup4RtBEEABMAGx-AAMlQ28xMUFahHaRE6JBuvQogmAaRAU0YzXYAG5NlZiLEQFIAO6fb4-AAsZL+II2rAQ4JabQ6BViMDAVng7HhgURyIJaIxmwAKuiYISCHgANYwABGuSI0GaLysEDAQxI52wtPsGkhxCZezsiwMRnpnOK3KRKP5EE4D2FirFkplcoVMFGKrV52U2GUiiAA