使用在多个位置返回数据的函数



编辑
如果data接受这样的东西,那就太好了:

{
error: boolean;
errorText: string;
...anyOtherProperties
}

我在这里的用例是,我想有一个函数来验证我的表单字段,但为此我需要传递我的"数据",它绑定了一个唯一的"接口",然后我需要返回修改后的"数据">
这里有一个例子:
const InvalidateAllFields = (error: unknown, data: UserInterface): UserInterface => {
if (error instanceof z.ZodError) {
const { fieldErrors } = error.flatten();
for (const key of Object.keys(data)) {
const indexKey = key as keyof UserInterface;
const error = fieldErrors[indexKey];
data[indexKey].error = !!error;
data[indexKey].errorText = error?.[0] ?? '';
}
}
return data;
};

由于UserInterface的原因,我无法真正将其用于其他形式,只能用于具有该接口的形式。

要在多个地方使用同一个函数,我需要做什么?

解决方案

多亏了@crashmstr,我做了一些研究,找到了问题的答案。使用泛型是解决这个问题的方法。

首先声明一个可以接收泛型并正确解析密钥的类型:

type DataType<T> = {
[key in keyof T]: { error: boolean; message: string };
};

然后,在声明函数时,重要的部分是将DataType扩展到泛型,然后使用泛型作为datareturn类型。

export const genericValidationFunc = <T extends DataType<T>>(
errors: Record<string, { error: boolean; message: string }>,
data: T
): T => {
for (const key of Object.keys(data)) {
const indexKey = key as keyof T;
data[indexKey].error = !!errors[key]?.error;
data[indexKey].message = errors[key]?.message ?? '';
}
return data;
};

现在,当你调用它在任何需要的地方使用时,它只会指出,如果你缺少DataType中所需的内容,其他任何内容都会被忽略。

例如

interface DataInterface {
mydata: { text: ''; error: boolean; message: string };
}
let data: DataInterface = {
mydata: { text: '', error: false, message: '' }
};

const errors = {
mydata: { error: true, message: 'Hello World' }
};
// Now this doesn't give a warning, even though text is not 
//defined on my function as one of the returned values
data = genericValidationFunc <DataInterface>(errors, data);

PS。尽管我对它进行了测试,并且它适用于我的用例,但由于我仍在学习打字脚本,所以这段代码中可能仍然存在问题。

最新更新