Skip to content

Commit e831412

Browse files
committed
Merge branch 'dev' of git://github.com/ealves-pt/vue into array-prop-checks
2 parents 1af0601 + d97d20e commit e831412

File tree

2 files changed

+83
-26
lines changed

2 files changed

+83
-26
lines changed

src/compiler/compile-props.js

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -287,36 +287,23 @@ export function assertProp (prop, value, vm) {
287287
}
288288
var options = prop.options
289289
var type = options.type
290-
var valid = true
291-
var expectedType
290+
var valid = !type
291+
var expectedTypes = []
292292
if (type) {
293-
if (type === String) {
294-
expectedType = 'string'
295-
valid = typeof value === expectedType
296-
} else if (type === Number) {
297-
expectedType = 'number'
298-
valid = typeof value === 'number'
299-
} else if (type === Boolean) {
300-
expectedType = 'boolean'
301-
valid = typeof value === 'boolean'
302-
} else if (type === Function) {
303-
expectedType = 'function'
304-
valid = typeof value === 'function'
305-
} else if (type === Object) {
306-
expectedType = 'object'
307-
valid = isPlainObject(value)
308-
} else if (type === Array) {
309-
expectedType = 'array'
310-
valid = isArray(value)
311-
} else {
312-
valid = value instanceof type
293+
if (!isArray(type)) {
294+
type = [ type ]
295+
}
296+
for (var i = 0; i < type.length && !valid; i++) {
297+
var assertedType = assertType(value, type[i])
298+
expectedTypes.push(assertedType.expectedType)
299+
valid = assertedType.valid
313300
}
314301
}
315302
if (!valid) {
316303
if (process.env.NODE_ENV !== 'production') {
317304
warn(
318305
'Invalid prop: type check failed for prop "' + prop.name + '".' +
319-
' Expected ' + formatType(expectedType) +
306+
' Expected ' + formatTypes(expectedTypes) +
320307
', got ' + formatValue(value) + '.',
321308
vm
322309
)
@@ -353,9 +340,46 @@ export function coerceProp (prop, value) {
353340
return coerce(value)
354341
}
355342

356-
function formatType (val) {
357-
return val
358-
? val.charAt(0).toUpperCase() + val.slice(1)
343+
function assertType (value, type) {
344+
var valid
345+
var expectedType
346+
if (type === String) {
347+
expectedType = 'string'
348+
valid = typeof value === expectedType
349+
} else if (type === Number) {
350+
expectedType = 'number'
351+
valid = typeof value === expectedType
352+
} else if (type === Boolean) {
353+
expectedType = 'boolean'
354+
valid = typeof value === expectedType
355+
} else if (type === Function) {
356+
expectedType = 'function'
357+
valid = typeof value === expectedType
358+
} else if (type === Object) {
359+
expectedType = 'object'
360+
valid = isPlainObject(value)
361+
} else if (type === Array) {
362+
expectedType = 'array'
363+
valid = isArray(value)
364+
} else {
365+
valid = value instanceof type
366+
}
367+
return {
368+
valid,
369+
expectedType
370+
}
371+
}
372+
373+
function formatTypes (types) {
374+
return types.reduce(
375+
(p, c, i) => { return i === 0 ? formatType(c) : `${p}, ${formatType(c)}` },
376+
''
377+
)
378+
}
379+
380+
function formatType (type) {
381+
return type
382+
? type.charAt(0).toUpperCase() + type.slice(1)
359383
: 'custom type'
360384
}
361385

test/unit/specs/directives/internal/prop_spec.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ describe('prop', function () {
364364
expect('Expected custom type').toHaveBeenWarned()
365365
})
366366

367+
it('multiple types', function () {
368+
makeInstance([], [Array, Number, Boolean])
369+
expect(getWarnCount()).toBe(0)
370+
makeInstance({}, [Array, Number, Boolean])
371+
expect('Expected Array, Number, Boolean').toHaveBeenWarned()
372+
})
373+
367374
it('custom validator', function () {
368375
makeInstance(123, null, function (v) {
369376
return v === 123
@@ -390,6 +397,21 @@ describe('prop', function () {
390397
expect('Expected String').toHaveBeenWarned()
391398
})
392399

400+
it('multiple types + custom validator', function () {
401+
makeInstance(123, [Number, String, Boolean], function (v) {
402+
return v === 123
403+
})
404+
expect(getWarnCount()).toBe(0)
405+
makeInstance(123, [Number, String, Boolean], function (v) {
406+
return v === 234
407+
})
408+
expect('custom validator check failed').toHaveBeenWarned()
409+
makeInstance(123, [String, Boolean], function (v) {
410+
return v === 123
411+
})
412+
expect('Expected String, Boolean').toHaveBeenWarned()
413+
})
414+
393415
it('type check + coerce', function () {
394416
makeInstance(123, String, null, String)
395417
expect(getWarnCount()).toBe(0)
@@ -401,6 +423,17 @@ describe('prop', function () {
401423
expect(getWarnCount()).toBe(0)
402424
})
403425

426+
it('multiple types + custom validator', function () {
427+
makeInstance(123, [String, Boolean, Number], null, String)
428+
expect(getWarnCount()).toBe(0)
429+
makeInstance('123', [String, Boolean, Number], null, Number)
430+
expect(getWarnCount()).toBe(0)
431+
makeInstance('123', [String, Boolean, Function], null, function (val) {
432+
return val === '123'
433+
})
434+
expect(getWarnCount()).toBe(0)
435+
})
436+
404437
it('required', function () {
405438
new Vue({
406439
el: document.createElement('div'),

0 commit comments

Comments
 (0)