问题描述
我正在寻找有关此问题的软件设计方面的好主意:
服务器发送一系列步骤:
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