Home > Net >  Discriminating items of filtered array of generic values in generic class
Discriminating items of filtered array of generic values in generic class

Time:11-12

I know that the question may be not too clear, but it's very difficult to phrase questions and find answers to such abstract cases, and I honestly don't know how to put it better.

I have the following code:

enum TagType {
    SIMPLE = 'simple',
    COLLECTOR = 'collector',
}

interface Tag {
    type: TagType,
}

interface SimpleTag extends Tag {
    type: TagType.SIMPLE,
}

interface CollectorTag extends Tag {
    type: TagType.COLLECTOR,
}

interface ServiceDefinition<T extends Tag> {
    tags: T[],
}

// This works.
const definition: ServiceDefinition<Tag> = {tags: []};
const collectorTags: CollectorTag[] = definition.tags.filter((t: Tag): t is CollectorTag => t.type === TagType.COLLECTOR);

// This doesn't work.
class CollectorDefinitionProcessor <T extends Tag> {
    process(definition: ServiceDefinition<T>): void {
        const collectorTags: CollectorTag[] = definition.tags.filter((t: T): t is CollectorTag => t.type === TagType.COLLECTOR);
    }
}

Playground

Why code in the class is wrong? How can we discriminate items of this array in the generic class like the one above?

CodePudding user response:

This happens because the definition.tags can contain all types of tags defined in the enum. You could explicitly cast the CollectorTags to your desired type like this:

class CollectorDefinitionProcessor<T extends Tag> {
  process(definition: ServiceDefinition<T>): void {
    const collectorTags: CollectorTag[] = definition.tags.filter(
      (t: T) => t.type === TagType.COLLECTOR
    ) as CollectorTag[]
  }
}
  • Related