Repository: vuejs/vue
Pull request: fix(props): correctly warn when a provided prop is Symbol

Fixes #10519

<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [x] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**


Changed files:
filename: src/core/util/props.js
patch: @@ -205,18 +205,19 @@ function getInvalidTypeMessage (name, value, expectedTypes) {
     ` Expected ${expectedTypes.map(capitalize).join(', ')}`
   const expectedType = expectedTypes[0]
   const receivedType = toRawType(value)
-  const expectedValue = styleValue(value, expectedType)
-  const receivedValue = styleValue(value, receivedType)
   // check if we need to specify expected value
-  if (expectedTypes.length === 1 &&
-      isExplicable(expectedType) &&
-      !isBoolean(expectedType, receivedType)) {
-    message += ` with value ${expectedValue}`
+  if (
+    expectedTypes.length === 1 &&
+    isExplicable(expectedType) &&
+    isExplicable(typeof value) &&
+    !isBoolean(expectedType, receivedType)
+  ) {
+    message += ` with value ${styleValue(value, expectedType)}`
   }
   message += `, got ${receivedType} `
   // check if we need to specify received value
   if (isExplicable(receivedType)) {
-    message += `with value ${receivedValue}.`
+    message += `with value ${styleValue(value, receivedType)}.`
   }
   return message
 }
@@ -231,9 +232,9 @@ function styleValue (value, type) {
   }
 }
 
+const EXPLICABLE_TYPES = ['string', 'number', 'boolean']
 function isExplicable (value) {
-  const explicitTypes = ['string', 'number', 'boolean']
-  return explicitTypes.some(elem => value.toLowerCase() === elem)
+  return EXPLICABLE_TYPES.some(elem => value.toLowerCase() === elem)
 }
 
 function isBoolean (...args) {

filename: test/unit/features/options/props.spec.js
patch: @@ -241,6 +241,16 @@ describe('Options props', () => {
         makeInstance({}, Symbol)
         expect('Expected Symbol, got Object').toHaveBeenWarned()
       })
+
+      it('warns when expected an explicable type but Symbol was provided', () => {
+        makeInstance(Symbol('foo'), String)
+        expect('Expected String, got Symbol').toHaveBeenWarned()
+      })
+
+      it('warns when expected an explicable type but Symbol was provided', () => {
+        makeInstance(Symbol('foo'), [String, Number])
+        expect('Expected String, Number, got Symbol').toHaveBeenWarned()
+      })
     }
 
     it('custom constructor', () => {