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);
}
}
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[]
}
}