【问题标题】:Discriminating items of filtered array of generic values in generic class区分泛型类中泛型值的过滤数组项
【发布时间】:2021-12-22 10:58:17
【问题描述】:

我知道这个问题可能不太清楚,但是对于这样抽象的案例来说,提出问题并找到答案是非常困难的,我真的不知道如何更好地表达。

我有以下代码:

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

为什么类中的代码是错误的?我们如何在上面的泛型类中区分这个数组的项目?

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    这是因为definition.tags 可以包含枚举中定义的所有类型的标签。 您可以像这样将 CollectorTags 显式转换为您想要的类型:

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

    【讨论】:

    • 但是过滤器中使用了相同的泛型类型,所以知道为什么 Typescript 不能在那里区分枚举值吗?这是一个错误还是有充分的理由?
    • 我不认为 Typescript 可以推断它是 CollectorTag 类型,因为它是唯一一个带有 type: TagType.COLLECTOR 的类型。在其他地方可能还有其他带有type: TagType.COLLECTOR 的标签(即使在其他文件中,尽管在您的情况下没有)。在 TS 方面考虑所有这些可能性太复杂了,这就是为什么我不认为这是一个错误。
    猜你喜欢
    • 1970-01-01
    • 2015-08-26
    • 2011-11-04
    • 2021-12-01
    • 2011-04-20
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多