简体   繁体   English

如何使用已由另一个 propType 接口定义的动态键和值来验证 propType 形状?

[英]How can I validate a propType shape with dynamic keys and values already defined by another propType interface?

Let's say I have the following prop-type interface for an user object :假设我为用户 object有以下道具类型接口:

const userPropType = shape({
  name: string,
  address: string,
  age: number    
});

Then I wanted to validate a global users' object received by props, that is comprised of several individual user objects , which keys are random numeric IDs.然后我想验证一个全局用户的 object由 props 接收,它由几个单独的用户对象组成,其中键是随机数字 ID。 For example:例如:

{
  3142: {
    name: 'Jonh Doe',
    address: 'Baker Street',
    age: 23 
  },
  4345: {
    name: 'Jane Doe',
    address: 'Fourth Avenue',
    age: 64 
  }
}

I know I can validate the numeric keys without trouble using a Prop Type custom validator.我知道我可以使用 Prop Type 自定义验证器毫无问题地验证数字键。 But the issue would be: how can I validate my global users' object using a custom handler that could validate the keys dynamically, but also the values based on my already defined userPropType interface.但问题是:如何使用可以动态验证密钥的自定义处理程序以及基于我已经定义的userPropType接口的值来验证我的全球用户的 object。

In this short example I could easily type check each of the user attributes on the custom validator, but if we consider a real case scenario where my user object could have more than 50 attributes, it would be pretty annoying to be custom validating each one of them, specially when I already have a defined propType for my single user object.在这个简短的示例中,我可以轻松地在自定义验证器上键入检查每个用户属性,但如果我们考虑一个真实的案例场景,即我的用户 object 可能有超过 50 个属性,自定义验证每个属性会很烦人他们,特别是当我已经为我的单个用户 object 定义了 propType 时。

So, that's the question: is it possible to use an already defined prop-type interface inside a custom validator?那么,问题来了:是否可以在自定义验证器中使用已经定义的 prop-type 接口?

Thanks!谢谢!

I've seen that this has not being answered yet.我已经看到这还没有得到回答。 As I could already find a solution, I share it here in the hope that it may be of any help of other fellow developers out there.因为我已经找到了解决方案,所以我在这里分享它,希望它可以对其他开发人员有所帮助。

I've implemented a custom validator that could check for me if the prop is indeed in the exact format I expect.我已经实现了一个自定义验证器,它可以检查道具是否确实符合我期望的格式。

To clarify, my 'users' prop should be an object with numeric keys (even if represented as strings) and have three attributes: name (string), address (string) and age (number).澄清一下,我的“用户”属性应该是带有数字键的 object(即使表示为字符串)并具有三个属性:名称(字符串)、地址(字符串)和年龄(数字)。

This is my custom implementation:这是我的自定义实现:

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
};

And here's a working demo, where you can change the type of the props sent by App to a Child component and see the PropType errors on the console:这是一个工作演示,您可以在其中将 App 发送的道具类型更改为子组件,并在控制台上查看 PropType 错误:

https://stackblitz.com/edit/react-4sunky?file=src/App.js https://stackblitz.com/edit/react-4sunky?file=src/App.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM