5

我有一个mongoose discriminator schema,这意味着数据会根据其中一个属性而有所不同。

class Feature {
  name: string
  option: ColorFeature|SizeFeature
}

class ColorFeature {
  kind: 'color'
  color: string
}

class SizeFeature {
  kind: 'size'
  size: number
}

Feature验证类以使其仅接受 2 种不同类型的正确方法是什么?

4

2 回答 2

7

它可以通过validateNested()class-transformer discriminator一起使用来实现

class BaseFeature {
  kind: 'size' | 'color'
}

class ColorFeature extends BaseFeature {
  kind: 'size'
  color: string
}

class SizeFeature extends BaseFeature {
  kind: 'size'
  size: number
}


class Feature {
  name: string

  @ValidateNested()
  @Type(() => BaseFeature, {
    keepDiscriminatorProperty: true,
    discriminator: {
      property: 'kind',
      subTypes: [
        { value: SizeFeature, name: 'size' },
        { value: ColorFeature, name: 'color' },
      ],
    },
  })
  option: SizeFeature | ColorFeature;
}
于 2020-04-24T04:23:59.637 回答
2

我花了很多时间来解决这个问题,我终于找到了一种比当前答案更干净的方法。

基本上,@Type如果我们想使用装饰器,装饰器会为我们提供一些辅助选项,比如我们..对象!因此,您可以有条件地返回一种或另一种类型,因此验证是通过以下两种类型之一完成的:

class Feature {
  name: string

  @ValidateNested()
  @IsDefined()
  @Type(({ object }) => {
    if(object.option?.kind === 'color') return ColorFeature;
    else if(object.option?.kind === 'size') return SizeFeature;
    // Handle edge case where the previous ifs are not fullfiled
  })
  option: ColorFeature | SizeFeature
}

如果您有更多类型,您甚至可以使用 aswitch case来保持清洁:

  @ValidateNested()
  @IsDefined()
  @Type(({ object }) => {
    switch(object.option?.kind){
      case 'color':
        return ColorFeature;
      case 'size':
        return SizeFeature;
      case 'shape':
        return ShapeFeature;
      default:
        // Manage edge cases
    }
  })
  option: ColorFeature | SizeFeature | ShapeFeature

然后,您还必须在扩展类中使用验证装饰器,以便正确验证它们。

于 2022-01-28T09:47:10.153 回答