1

I have an abstract class:

abstract class TableAdapter {
    public abstract convertInputToOutput<InputType, OutputType> (apiRow: InputType): OutputType;
}

Now I am going to inherit from it for a set of classes:

class TableAdapter1 extends TableAdapter {

    public convertInputToOutput (apiRow: InputType1): OutputType1 {
        // return something of type OutputType1;
    }
}

class TableAdapter2 extends TableAdapter {

    public convertInputToOutput (apiRow: InputType2): OutputType2 {
        // return something of type OutputType2;
    }
}

I see an error while compiling:

Types of parameters 'apiRow' and 'apiRow' are incompatible. Type 'ApiRowType' is not assignable to type 'InputType1'

How do I fix it and set exact types in an inheriting class so that I could access objects' fields?

2 Answers 2

1

try extending a generic class, modify you abstract class to abstract class TableAdapter<InputType, OutputType> and extend your TableAdapter1 like class TableAdapter1 extends TableAdapter<InputType1, OutputType1>

abstract class TableAdapter<InputType, OutputType> {
    public abstract convertInputToOutput(apiRow: InputType): OutputType;
}

class TableAdapter1 extends TableAdapter<InputType1, OutputType1> {
    public convertInputToOutput (apiRow: InputType1): OutputType1 {
    }
}

class TableAdapter2 extends TableAdapter<InputType2, OutputType2> {
    public convertInputToOutput (apiRow: InputType2): OutputType2 {
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

One of the interesting things about TypeScript is that many of the situations you might have in nominal languages that require you to reach for generics can be handled without them in TypeScript.

That isn't to say your specific scenario can be done without generics, but it is worth considering the example below.

If you have a minimal interface that all input types and outputs types must adhere to, you could achieve this without generics, thanks to the structural type system.

For example, if you need your input type to minimally have a name, but it could also have other properties, you can achieve this without generics. For the example, we'll use a couple of interfaces, but you don't necessarily need these - structures will do... the same goes for the output types.

interface InputType {
    name: string;
}

interface InputType1 extends InputType {
    location: string;
}

interface InputType2 {
    name: string;
}

Your code will be checked for structural compatibility, without the need for generics:

abstract class TableAdapter {
    public abstract convertInputToOutput(apiRow: InputType): OutputType;
}

class TableAdapter1 extends TableAdapter {
    public convertInputToOutput(apiRow: InputType1): OutputType1 {
        return { name: '', location: '' };
    }
}

class TableAdapter2 extends TableAdapter {
    public convertInputToOutput(apiRow: InputType2): OutputType2 {
        return { name: '' };
    }
}

Any if you are happy for the input and output types to be literally anything, the abstract class could say it is happy for them to be any type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.