如何使用另一个 propType 接口定义的动态键和值来验证 propType 形状?
How can I validate a propType shape with dynamic keys and values already defined by another propType interface?
假设我有一个用户对象的道具类型接口:
const userPropType = shape({
name: string,
address: string,
age: number
});
然后我想验证 props 接收的 全局用户对象 ,它由几个单独的 用户对象 组成,其中键是随机数字 ID。
例如:
{
3142: {
name: 'Jonh Doe',
address: 'Baker Street',
age: 23
},
4345: {
name: 'Jane Doe',
address: 'Fourth Avenue',
age: 64
}
}
我知道我可以使用 Prop Type 自定义验证器毫无问题地验证数字键。但问题是:我如何使用自定义处理程序来验证我的全局用户对象,该处理程序可以动态验证密钥,但也可以根据我已经定义的 userPropType 接口验证值。
在这个简短的示例中,我可以轻松地检查自定义验证器上的每个用户属性,但是如果我们考虑一个真实的案例场景,我的用户对象可能有超过 50 个属性,那么自定义验证它们中的每一个,特别是当我已经为我的单个用户对象定义了 propType 时。
所以,这就是问题所在:是否可以在自定义验证器中使用已经定义的 prop 类型接口?
谢谢!
我看到这个问题还没有得到解答。因为我已经找到了解决方案,所以我在这里分享它,希望它可能对其他开发人员有任何帮助。
我已经实现了一个自定义验证器,它可以为我检查道具是否确实是我期望的格式。
澄清一下,我的 'users' 属性应该是一个带有数字键的对象(即使表示为字符串)并且具有三个属性:名称(字符串)、地址(字符串)和年龄(数字)。
这是我的自定义实现:
const usersObjectPropType = (
propValue,
key,
componentName
) => {
let isNotValid;
const userKeys = Object.keys(propValue.users);
const userValues = Object.values(propValue.users);
const allKeysAreNumeric = userKeys.every(key => !Number.isNaN(Number(key)));
userValues.forEach(user => {
if (typeof user.name !== 'string') {
isNotValid = ['name', 'string', user.name];
} else if (typeof user.address !== 'string') {
isNotValid = ['address', 'string', user.address];
} else if (typeof user.age !== 'number') {
isNotValid = ['age', 'number', user.age];
}
});
if (!allKeysAreNumeric) {
return new Error(
`Invalid prop '${key}' supplied to ${componentName} component. The keys for the '${key}' object should have the type 'number'.`
);
}
if (isNotValid) {
return new Error(
`Invalid prop in '${key}' object supplied to ${componentName} component. The type of '${
isNotValid[0]
}' attribute provided was '${typeof isNotValid[2]}' and a '${
isNotValid[1]
}' was expected.`
);
}
};
Child.propTypes = {
users: usersObjectPropType
};
这是一个工作演示,您可以在其中更改 App 发送到子组件的道具类型,并在控制台上查看 PropType 错误:
假设我有一个用户对象的道具类型接口:
const userPropType = shape({
name: string,
address: string,
age: number
});
然后我想验证 props 接收的 全局用户对象 ,它由几个单独的 用户对象 组成,其中键是随机数字 ID。 例如:
{
3142: {
name: 'Jonh Doe',
address: 'Baker Street',
age: 23
},
4345: {
name: 'Jane Doe',
address: 'Fourth Avenue',
age: 64
}
}
我知道我可以使用 Prop Type 自定义验证器毫无问题地验证数字键。但问题是:我如何使用自定义处理程序来验证我的全局用户对象,该处理程序可以动态验证密钥,但也可以根据我已经定义的 userPropType 接口验证值。
在这个简短的示例中,我可以轻松地检查自定义验证器上的每个用户属性,但是如果我们考虑一个真实的案例场景,我的用户对象可能有超过 50 个属性,那么自定义验证它们中的每一个,特别是当我已经为我的单个用户对象定义了 propType 时。
所以,这就是问题所在:是否可以在自定义验证器中使用已经定义的 prop 类型接口?
谢谢!
我看到这个问题还没有得到解答。因为我已经找到了解决方案,所以我在这里分享它,希望它可能对其他开发人员有任何帮助。
我已经实现了一个自定义验证器,它可以为我检查道具是否确实是我期望的格式。
澄清一下,我的 'users' 属性应该是一个带有数字键的对象(即使表示为字符串)并且具有三个属性:名称(字符串)、地址(字符串)和年龄(数字)。
这是我的自定义实现:
const usersObjectPropType = (
propValue,
key,
componentName
) => {
let isNotValid;
const userKeys = Object.keys(propValue.users);
const userValues = Object.values(propValue.users);
const allKeysAreNumeric = userKeys.every(key => !Number.isNaN(Number(key)));
userValues.forEach(user => {
if (typeof user.name !== 'string') {
isNotValid = ['name', 'string', user.name];
} else if (typeof user.address !== 'string') {
isNotValid = ['address', 'string', user.address];
} else if (typeof user.age !== 'number') {
isNotValid = ['age', 'number', user.age];
}
});
if (!allKeysAreNumeric) {
return new Error(
`Invalid prop '${key}' supplied to ${componentName} component. The keys for the '${key}' object should have the type 'number'.`
);
}
if (isNotValid) {
return new Error(
`Invalid prop in '${key}' object supplied to ${componentName} component. The type of '${
isNotValid[0]
}' attribute provided was '${typeof isNotValid[2]}' and a '${
isNotValid[1]
}' was expected.`
);
}
};
Child.propTypes = {
users: usersObjectPropType
};
这是一个工作演示,您可以在其中更改 App 发送到子组件的道具类型,并在控制台上查看 PropType 错误: