我应该如何使用React / Typescript设计:服务器发送步骤列表每个步骤都有一个类型和有效负载

问题描述

我正在寻找有关此问题的软件设计方面的好主意:

服务器发送一系列步骤:

type StepTypeEnum = 'Security' | 'PERSONAL_DETAILS' | ... ;
type Step = { stepType: StepTypeEnum,payload: ??? };
StepsController.GET(): Array<Step>;

客户端接收步骤数组,并使用React呈现每个步骤。

每个步骤都有不同的呈现组件和有效负载类型。例如:

const Security = ({ username,password }) => <span>...</span>;
const PersonalDetails = ({ firstName,surName }) => <span>...</span>;
// etc...

通过键入实现它的最佳方法是什么? 我想到的第一个想法是Factory模式,但我不确定如何处理payload可以是任何类型的事实。我应该只键入任意一个并将其向下转换到组件中吗?

例如,我现在所拥有的:

const Factory = step => ({
  Security: ({payload}) => <Security username={payload.username} password={payload.password} />,PERSONAL_DETAILS = ({payload}) => <PersonalDetails firstName={payload.firstName} ... />
}[step.type])

const Component = Factory(step);
<Component payload={payload} />

这迫使我使用any来描述有效载荷类型

解决方法

这是一个相当常见的设计模式。您所做的工作与type checking actions and action creators的此redux部分中描述的内容相同。

您想要做的是为public static int maxSubArray(int[] a,out int[] subArr){ int sumMax = int.MinValue; int subSum = 0; int iLow = 0,iHigh = 0; for(int i=0; i<a.Length; i++){ subSum+=a[i]; if(subSum>sumMax){ sumMax = subSum; //move high (upper bound) since sumMax increased iHigh = i; //if the subSum is new,then move lower bound if(subSum == a[i]){ iLow = i; } } subSum = Math.Max(subSum,0); } //build the array - returned as an out parameter int index = 0; subArr = new int[iHigh-iLow+1]; while(iLow <= iHigh){ subArr[index++] = a[iLow++]; } return sumMax; } stepType的每个特定配对指定一个类型。然后,您可以将广义payload类型定义为所有有效配对的并集。现在,当您检查Step是否为stepType时,打字稿会知道有效负载类型只能是带有安全步骤的类型。 (确保在检查之前不破坏结构,否则将无法正常工作。)

我们将首先定义props / payload接口,因为我们可以在步骤中使用与渲染组件相同的接口。

'SECURITY'

现在,我们创建步骤的并集。我们可以分别定义它们,然后进行组合,但是我将一步编写和组合它们。如果您需要,我们可以通过查看工会中的interface SecurityProps { username: string; password: string; } interface PersonalDetailsProps { firstName: string; surName: string; } const Security = ({ username,password }: SecurityProps) => <span>{username}</span>; const PersonalDetails = ({ firstName,surName }: PersonalDetailsProps) => <span>{`${firstName} ${surName}`}</span>; 来获得您的StepTypeEnum

stepTypes

我们需要一个可以呈现任何type Step = { stepType: 'SECURITY'; payload: SecurityProps; } | { stepType: 'PERSONAL_DETAILS'; payload: PersonalDetailsProps; } type StepTypeEnum = Step['stepType']; 的组件。像您所拥有的地图都可以,但是我将使用Step来代替,因为不需要额外的输入。我们的联合体类型可以完成所有繁重的工作。

switch