Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing generics from inherited type

Tags:

typescript

I am trying to access generics from another class, which will be passed as a generic itself.

export default abstract class Foo<K, V> {}
import Foo from './Foo';
export default abstract class Bar<Foo> {}

How would I go about accessing the K and V within Bar class? I would like to create an abstract method that uses these types, but I'm not sure how I would actually access the nested generic.

Edit: Added use case for more clarification

Example use case:

export default class Baz extends Foo<string, number> {}
import Baz from './Baz';
export default class Qux extends Bar<Baz> {}

I would like the Bar class to recognise that Qux should hold the generics <string, number>, as I want to have an abstract method within Bar that follows the signature

public abstract foo(thing: string): number;

as an example.

An alternative that I have considered: passing Baz within the constructor instead of as a generic type... However, there still is an issue of actually getting the generic types from the Baz itself.

Edit 2: Actual use-case

Okay, so I have these 2 classes.

export default abstract class Storage<K, V> {
    protected abstract _init(): void;
}
import Data from '../structures/bases/Data';
export default class DataStore extends Storage<string, Data> {
    protected async _init(): void {
        // ...
    }
}

Here's where the issues comes in

import Data from '../structures/bases/Data';
export default class DataHandler extends Handler<DataStore> {
    public abstract get(key: string): Data {
        //...
    }
}
export default abstract class Handler<K, V> {
    // my goal, where K is string and V is Data when DataStore is passed
    public abstract get(key: K): V;
}

I am going to have several *Handlers where I would pass an instance of an extended Storage as the generic. Now obviously I can't magically plug in K and V, what I can do instead I suppose is have Handler<K, V> and then pass <string, Command>, but I was hoping that I could simply pass the instance of *Storage instead of passing the 2 types again everytime.

like image 275
codes Avatar asked Dec 16 '25 20:12

codes


1 Answers

Your definition of Bar is incorrect. It should look something like this:

import Foo from './Foo';
export default abstract class Bar<K, V, F extends Foo<K,V>> {}

Your original Foo was a type variable inside of bar and not the Foo class you want it to be. And then K and V are bound to the type variables of the instance of Foo. And now, all of the type variables are available in your Bar instance

This is a bit of a monster, but using type variables can quickly get out of hand.

like image 147
Andrew Eisenberg Avatar answered Dec 19 '25 14:12

Andrew Eisenberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!