【问题标题】:Mixin Type pattern not workingMixin 类型模式不起作用
【发布时间】:2018-08-27 11:39:31
【问题描述】:

我正在为 AWS 的 Step Function 配置创建一个类型,并且可以组成一个函数的各种“状态”包括:{

export type StepFunctionState = IStepFunctionTask 
    & IStepFunctionChoice 
    & IStepFunctionWait;

我正在使用“mixin”模式,以便状态可以是不同类型状态的任意组合。各种状态定义是:

export interface IStepFunctionTask extends IStepFunctionBaseState {
  Type: "Task";
  /** of the format arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${opt:stage}-FUNCTION_NAME */
  Resource: AwsFunctionArn;
  Next?: string;
  End?: true;
  Retry?: [
    {
      ErrorEquals: string[];
      IntervalSeconds: number;
      BackoffRate: number;
      MaxAttemps: number;
    }
  ];
  Catch?: [
    {
      ErrorEquals: string[];
      Next: string;
    }
  ];
}

export interface IStepFunctionChoice extends IStepFunctionBaseState {
  Type: "Choice";
  Choices: [
    {
      /** points to the specific area of context which is being evaluated in the choice */
      Variable: string;
      /** compare the value passed in -- and scoped by "Variable" -- to be numerically equal to a stated number */
      NumericEquals?: number;
      /** the next state to move to when completed with this one */
      Next?: string;
      /** the step-function should stop at this step */
      End?: boolean;
    }
  ];
}

export interface IStepFunctionWait extends IStepFunctionBaseState {
  Type: "Wait";
  Seconds: number;
  Next: AwsFunctionArn;
}

其中IStepFunctionBaseState 只是加强了所需的Type 属性,这是可区分联合的关键部分:

export interface IDictionary<T = any> {
  [key: string]: T;
}
export type IStepFunctionType = "Task" | "Wait" | "Choice";
export interface IStepFunctionBaseState {
  Type: IStepFunctionType;
}

然后我可以为这些任务类型中的每一个分配合理的数据结构:

const wait: IDictionary<IStepFunctionWait> = {
  yyy: {
    Type: "Wait",
    Seconds: 12,
    Next: "foo"
  }
};

const task: IDictionary<IStepFunctionTask> = {
  xxx: {
    Type: "Task",
    Resource: "arn",
    Next: "x2"
  },
  x2: {
    Type: "Task",
    Resource: "arn2",
    End: true
  }
};

const pass: IDictionary<IStepFunctionPass> = {
  pass: {
    Type: "Pass",
    Result: {
      foo: 1,
      bar: 2
    },
    ResultPath: "$.info",
    Next: "baz"
  }
};

const choice: IDictionary<IStepFunctionChoice> = {
  zzz: {
    Type: "Choice",
    Choices: [
      {
        Variable: "$.bar",
        NumericEquals: 1,
        Next: "xxx"
      }
    ]
  }
};

这一切都有效,但以下不起作用:

const mixedBag: IDictionary<StepFunctionState> = {
  ...task,
  ...choice,
  ...wait
};

我在抱怨的mixedBag 的定义中遇到了一些错误:

类型'{类型:“任务”;资源:字符串;下一个?:字符串;结束?:是的;重试?: [{ ErrorEquals: string[]; In...' 不能分配给类型 '{ Type: "Task";资源:字符串;下一个?:字符串;结束?:是的;重试?: [{ ErrorEquals: string[];在...'。存在同名的两种不同类型,但它们不相关。

还有

类型'{类型:“选择”中缺少属性“资源”;选择: [{ 变量:字符串; NumericEquals?:数字;下一个?:字符串;结束?:布尔...'。

希望这足以让人们提供帮助,但如果您需要更多信息,请告诉我。

【问题讨论】:

  • 你能说明IStepFunctionChoiceIStepFunctionWait的定义吗?用实际代码替换该图片也会有所帮助。
  • 我现在会添加,但我很确定这不是该区域的问题。
  • 能否也添加代码而不是初始化代码的图片,以便更容易复制粘贴和测试:)
  • 我已经更新了代码而不是图像;我最初发布图片是为了说明没有错误,但我可以看到文字对人们更有用。

标签: typescript


【解决方案1】:

问题是当您希望对象具有联合中的所有属性时使用intersection types (&amp;)(因此所有步骤将同时具有IStepFunctionTaskIStepFunctionChoiceIStepFunctionWait 的所有属性时间)。显然,任务将是 IStepFunctionWaitIStepFunctionChoiceIStepFunctionTask,可以使用联合类型 (|) 进行建模

export type StepFunctionState = IStepFunctionTask 
    | IStepFunctionChoice 
    | IStepFunctionWait;

const mixedBag: IDictionary<StepFunctionState> = {
    ...task,
    ...choice,
    ...wait
};

【讨论】:

  • 让我再试一次......我在两者之间交替,但我的理解是,如果 Dictionary 能够拥有混合了 Task、Choice 的属性,&amp; 运算符是正确的, 和 Wait 状态,而当字典具有 Tasks、Choices 等但不是混合时,您将使用 | 运算符。
  • 好吧,我很高兴能得到纠正……这确实适用于 | 运算符。感谢您的推动。
猜你喜欢
  • 2016-12-02
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2015-05-14
  • 2021-07-22
  • 2013-08-11
相关资源
最近更新 更多