@@ -14,6 +14,7 @@ import {
14
14
extend ,
15
15
hasOwn ,
16
16
camelize ,
17
+ toRawType ,
17
18
capitalize ,
18
19
isBuiltInTag ,
19
20
isPlainObject
@@ -155,11 +156,19 @@ LIFECYCLE_HOOKS.forEach(hook => {
155
156
* a three-way merge between constructor options, instance
156
157
* options and parent options.
157
158
*/
158
- function mergeAssets ( parentVal : ?Object , childVal : ?Object ) : Object {
159
+ function mergeAssets (
160
+ parentVal : ?Object ,
161
+ childVal : ?Object ,
162
+ vm ? : Component ,
163
+ key : string
164
+ ) : Object {
159
165
const res = Object . create ( parentVal || null )
160
- return childVal
161
- ? extend ( res , childVal )
162
- : res
166
+ if ( childVal ) {
167
+ process . env . NODE_ENV !== 'production' && assertObjectType ( key , childVal , vm )
168
+ return extend ( res , childVal )
169
+ } else {
170
+ return res
171
+ }
163
172
}
164
173
165
174
ASSET_TYPES . forEach ( function ( type ) {
@@ -172,12 +181,20 @@ ASSET_TYPES.forEach(function (type) {
172
181
* Watchers hashes should not overwrite one
173
182
* another, so we merge them as arrays.
174
183
*/
175
- strats . watch = function ( parentVal : ?Object , childVal : ?Object ) : ?Object {
184
+ strats . watch = function (
185
+ parentVal : ?Object ,
186
+ childVal : ?Object ,
187
+ vm ?: Component ,
188
+ key : string
189
+ ) : ?Object {
176
190
// work around Firefox's Object.prototype.watch...
177
191
if ( parentVal === nativeWatch ) parentVal = undefined
178
192
if ( childVal === nativeWatch ) childVal = undefined
179
193
/* istanbul ignore if */
180
194
if ( ! childVal ) return Object . create ( parentVal || null )
195
+ if ( process . env . NODE_ENV !== 'production' ) {
196
+ assertObjectType ( key , childVal , vm )
197
+ }
181
198
if ( ! parentVal ) return childVal
182
199
const ret = { }
183
200
extend ( ret , parentVal )
@@ -200,7 +217,15 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
200
217
strats . props =
201
218
strats . methods =
202
219
strats . inject =
203
- strats . computed = function ( parentVal : ?Object , childVal : ?Object ) : ?Object {
220
+ strats . computed = function (
221
+ parentVal : ?Object ,
222
+ childVal : ?Object ,
223
+ vm ?: Component ,
224
+ key : string
225
+ ) : ?Object {
226
+ if ( childVal && process . env . NODE_ENV !== 'production' ) {
227
+ assertObjectType ( key , childVal , vm )
228
+ }
204
229
if ( ! parentVal ) return childVal
205
230
const ret = Object . create ( null )
206
231
extend ( ret , parentVal )
@@ -237,7 +262,7 @@ function checkComponents (options: Object) {
237
262
* Ensure all props option syntax are normalized into the
238
263
* Object-based format.
239
264
*/
240
- function normalizeProps ( options : Object ) {
265
+ function normalizeProps ( options : Object , vm : ? Component ) {
241
266
const props = options . props
242
267
if ( ! props ) return
243
268
const res = { }
@@ -261,14 +286,20 @@ function normalizeProps (options: Object) {
261
286
? val
262
287
: { type : val }
263
288
}
289
+ } else if ( process . env . NODE_ENV !== 'production' && props ) {
290
+ warn (
291
+ `Invalid value for option "props": expected an Array or an Object, ` +
292
+ `but got ${ toRawType ( props ) } .` ,
293
+ vm
294
+ )
264
295
}
265
296
options . props = res
266
297
}
267
298
268
299
/**
269
300
* Normalize all injections into Object-based format
270
301
*/
271
- function normalizeInject ( options : Object ) {
302
+ function normalizeInject ( options : Object , vm : ? Component ) {
272
303
const inject = options . inject
273
304
const normalized = options . inject = { }
274
305
if ( Array . isArray ( inject ) ) {
@@ -282,6 +313,12 @@ function normalizeInject (options: Object) {
282
313
? extend ( { from : key } , val )
283
314
: { from : val }
284
315
}
316
+ } else if ( process . env . NODE_ENV !== 'production' && inject ) {
317
+ warn (
318
+ `Invalid value for option "inject": expected an Array or an Object, ` +
319
+ `but got ${ toRawType ( inject ) } .` ,
320
+ vm
321
+ )
285
322
}
286
323
}
287
324
@@ -300,6 +337,16 @@ function normalizeDirectives (options: Object) {
300
337
}
301
338
}
302
339
340
+ function assertObjectType ( name : string , value : any , vm : ?Component ) {
341
+ if ( ! isPlainObject ( value ) ) {
342
+ warn (
343
+ `Invalid value for option "${ name } ": expected an Object, ` +
344
+ `but got ${ toRawType ( value ) } .` ,
345
+ vm
346
+ )
347
+ }
348
+ }
349
+
303
350
/**
304
351
* Merge two option objects into a new one.
305
352
* Core utility used in both instantiation and inheritance.
@@ -317,8 +364,8 @@ export function mergeOptions (
317
364
child = child . options
318
365
}
319
366
320
- normalizeProps ( child )
321
- normalizeInject ( child )
367
+ normalizeProps ( child , vm )
368
+ normalizeInject ( child , vm )
322
369
normalizeDirectives ( child )
323
370
const extendsFrom = child . extends
324
371
if ( extendsFrom ) {
0 commit comments