0

I want to initialize a generic class variable inside a generic class using a generic type, but I can't figure out if there is a way to do this.

Initializing with types works fine, it doesn't seem like it work with generics though.

type EventCallback<I, O> = (event: I) => O;

type ListenerList<K extends string | symbol | number, I, O, V extends EventCallback<I, O>> = {
    [T in K]: V[];
};

const test: ListenerList<string, string, string, (event: any) => any> = {}; // Works fine

export default class EventProcesser<
  K extends string | symbol | number,
  I,
  O,
  V extends EventCallback<I, O>
> {
  private listeners: ListenerList<K, I, O, V> = {}; // Error :(
}

I get the following error Type '{}' is not assignable to type 'ListenerList<K, I, O, V>'. Is there a way to do this?

2
  • ListenerList is assuming, that the object has at least one property. Adding a questionmark behind the [T in K] you are safe to go, because you are telling typescript, that there is at least zero properties in the object. Commented May 20, 2019 at 14:02
  • Thanks, this also works! Commented May 20, 2019 at 14:22

1 Answer 1

1

K can be a string literal type, so EventProcesser<'prop', ..> is valid meaning that listeners must have property named prop. This means that your default will not be valid for any K passed in as it should be.

You can use Partial to let the compiler know that no properties will be required:

type EventCallback<I, O> = (event: I) => O;

type ListenerList<K extends string | symbol | number, I, O, V extends EventCallback<I, O>> = {
    [T in K]: V[];
};

const test: ListenerList<string, string, string, (event: any) => any> = {}; // Works fine

export default class EventProcesser<
    K extends string | symbol | number,
    I,
    O,
    V extends EventCallback<I, O>
    > {
    private listeners: Partial<ListenerList<K, I, O, V>> = {}; // ok
}
Sign up to request clarification or add additional context in comments.

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.