2

Is there any way to track nested property types on Vue?

I have this props setup:

// ...
props: {
    navigation: {
        type: [Array],
        default: () => {
            return [
                { type: String, icon: "home" },
                { type: String, icon: "star" }
            ]
        }
    }
}

right now i have validation only for first level which is array, but nothing happens inside of it. Can i check types inside one of type level? Thx for help.

7
  • What do you mean by "track nested property types"? Do you mean, be able to assign types to them and have the compiler warn you when you are not complying with those types? Commented May 11, 2017 at 11:14
  • yeap, that's right Commented May 11, 2017 at 11:15
  • And are you referring to the return type from the default function? Commented May 11, 2017 at 11:15
  • yes, but what with the next level, i.e. of this icon strings? Commented May 11, 2017 at 11:16
  • What do you want navigation to be? You have currently said it's type should be an Array but the default function you have defined returns an array of objects (with keys type and icon). Note from the examples in the docs you posted it doesn't look like you type the return value from the default function. Commented May 11, 2017 at 12:04

3 Answers 3

4

I don't think it's possible to directly type the array of objects using the type attribute as Vue prop validation says:

The type can be one of the following native constructors:

  • String
  • Number
  • Boolean
  • Function
  • Object
  • Array
  • Symbol

Having said that it looks like you could define a validator function like:

props: {
    navigation: {
        validator: function (value) {
            if (!(value instanceof Array)) {
                return false;
            }
            for(var i = 0; i < value.length; ++i) {
                if (typeof value.icon !== "string") {
                    return false;
                }
            }
            return true;
        },
        default: () => {
            return [
                {icon: "home" },
                {icon: "star" }
            ]
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Great but i'm not using typescript, i just want to do this using only Vue it self, and delivered features - misunderstanding
Ah ok, you should remove the typescript tag from your question then. What is your question? Does Vue.js support a kind of type system of it's own using the type: attributes? Can you point towards the docs that mention that?
hehehe, this validator is so hardcore, imagine that i have to define it for each data type and each component :) but thx for trying, cheers and good day, now i'm pretty sure that i will install typescript :D
2

In addition to typescript and library like vue-types, I find _.every and _.has from lodash can make pretty readable solution for validating complicated prop.

import every from 'lodash/every'
import has from 'lodash/has'

export default {
  name: 'navigation',
  props: {
    items: {
      type: Array,
      validator: items =>
        every(items, (item) =>
          has(item, 'home') &&
          has(item, 'star')
        )
    }
  }
}

You can even write has(item, 'home.adress.zip') for deep nest object!

Comments

2

vue-types makes this easy to do. In the following example, notice the Array of strings:

    props: {

        picNum: VueTypes.number.def( 3 ),
        pics: VueTypes.arrayOf( String ).isRequired, // RIGHT HERE!
        step: VueTypes.number.def( 1 ),
        className: VueTypes.string.def( '' ),

    },

Plus vue-types has more helpers for defining the shape of objects, etc. Super nice to use with Vue props!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.