'Use field of a class member in another class member's generic defition

I'm making an ECS and this is the code I have for the System class, which will hold behavior:

type Trigger<Components extends Component, Query = Components['type'][]> = (...components: ComponentSet<Components, Query>) => void;

interface Query<Components extends Component> {
    withAll: Components['type'][]
}

abstract class System<Components extends Component> {
    query: Query<Components>;
    
    constructor(query: Query<Components>) {
        this.query = query;
    }

    abstract onFrame: Trigger<Components, this.query.withAll>;
} 

ComponentSet is a type that takes an array of component types (["Health", "Inventory"]) and transforms it into its actual component values ({health: number}, {activeSlot: number}). What is strange is that the above does not work, I get a syntax error on the last line, the one declaring an abstract member onFrame. But when I change this.query.withAll to a literal, such as:

abstract onFrame: Trigger<Components, ["Health"]>;

Then TypeScript throws no issue. Why is it that a literal works fine but a variable access does not work, despite both having the same type? Is there a way to work around this or solve this?

FYI Components['type'] is a string, the Component interface I've defined elsewhere ensures this.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source