Typescript abstract property not getting function arg types

Stack Overflow Asked by mpcaddy on November 18, 2020

I am trying to create a generic abstract class to be able to pass a type in to force developers to implement the types that are passed in. But for some reason the params of the functions are being typed as any unless I further type the property in the class extending the abstract.

Below are stripped down classes of what I am trying to achieve.

In Generic1 the params are both types as any, but the return type is correct.
In Generic2 the params are the correct type as well as the return type, but have needed to add the typing of the control property again to get it to work.

Am I missing something? I’d prefer to use Generic1 but not sure if it is possible.

declare type Signiture<L> = {
    [E in keyof L]: [any, any?];

declare type ControlSignature<L extends Signiture<L>> = {
    [E in keyof L]: (params: L[E][0]) => Promise<L[E][1]>;

abstract class Abstract<
    C extends Signiture<C> = {[messageName: string]: [any, any?] | [void, any?]}
> {
    protected abstract control: ControlSignature<C>;

interface X { 
    test1: [{ hello: string }, { world: string }],
    test2: [{ nothing: number }, { something: number }],

class Generic1 extends Abstract<X> {
    control = {
        test1: async (params) => {
            return { world: "test" }
        test2: async (params) => {
            return { something: 1 }

class Generic2 extends Abstract<X> {
    control: ControlSignature<X> = {
        test1: async (params) => {
            return { world: "test" }
        test2: async (params) => {
            return { something: 1 }

One Answer

This is unfortunately a design limitation of TypeScript, at least as of TS 4.0.

Currently, initialized properties of a subclass that are not explicitly annotated are inferred to have the type of the initializing value, without paying attention to the superclass.

There's an open issue (quite old at this point), microsoft/TypeScript#10570, tracking the suggestion to inherit typing for initialized properties from their superclasses. You might want to go to the issue above and give it a ? to record your desire for this to happen, but I doubt it will have much of an effect.

It seems that people are generally unhappy with the current behavior. But previous attempts to address this, microsoft/TypeScript#6118 and microsoft/TypeScript#10610 failed because they either gave weird results in common use cases (e.g., using contextual typing), or because they broke real-world code that relies on the current behavior.

Since it would be a breaking change to require users who want the current narrowing behavior to explicitly annotate their subproperties, it's not clear how to move forward. Breaking changes are generally avoided unless they have absolutely clear benefits that outweigh the effort of fixing real code bases that depend on TypeScript. There are a number of TypeScript features which were arguably implemented "the wrong way", but they are not egregious enough to warrant destabilizing current users; if you have a spare time machine and don't want to try to prevent various historical disasters you could fix these instead.

In the current timeline, it might be hard to make case that it's worth breaking existing code that relies on properties getting the type of the initializer, when the workaround of annotating the property yourself is easy enough to do.

So for now I'd say just annotate the properties yourself and move on.

Correct answer by jcalz on November 18, 2020

Add your own answers!

Related Questions

How to get the difference of two vectors A – B

2  Asked on February 28, 2021 by kacie-freeman


Calculate Year-Over-Year Change in DataTable

1  Asked on February 28, 2021 by sar


How to print diagonal star pattern in C

3  Asked on February 27, 2021 by amrit-singh


Working on evalExpr :: can’t fix an error?

1  Asked on February 27, 2021 by brahimi-haroun


How to access index in position method of iter?

4  Asked on February 26, 2021 by girkovarpa


getting info about How much you scrolled on a app?

0  Asked on February 26, 2021 by lakshan-costa


Trying to pass numpy array mode value to df column

1  Asked on February 25, 2021 by coderman


PHP why doesn´t the foreach function work?

1  Asked on February 25, 2021 by paperperson


Ask a Question

Get help from others!

© 2022 All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir