From f73387f9ee9129108ffaa567fad953ca58fdd2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Wed, 9 Feb 2022 17:14:50 +0800 Subject: [PATCH] fix(utils): undefined when omiting prop default (#5868) --- packages/utils-v2/tests/prop.spec.ts | 37 ++++++++++++++++++++++++++++ packages/utils-v2/vue/prop.ts | 17 ++++++++----- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/utils-v2/tests/prop.spec.ts b/packages/utils-v2/tests/prop.spec.ts index 179ef9edb5..df1aa99f73 100644 --- a/packages/utils-v2/tests/prop.spec.ts +++ b/packages/utils-v2/tests/prop.spec.ts @@ -1,5 +1,7 @@ /* eslint-disable @typescript-eslint/ban-types */ +import { defineComponent } from 'vue' +import { mount } from '@vue/test-utils' import { expectTypeOf } from 'expect-type' import { buildProp, definePropType, mutable, keyOf, buildProps } from '..' import type { propKey } from '../vue/prop' @@ -444,3 +446,38 @@ describe('buildProps', () => { }>() }) }) + +describe('runtime', () => { + it('default value', () => { + const warnHandler = jest.fn() + + const Foo = defineComponent({ + props: buildProps({ + bar: { type: Boolean }, + baz: { values: ['a', 'b', 'c'] }, + qux: { values: ['a', 'b', 'c'], required: true }, + qux2: { values: ['a', 'b', 'c'], required: true }, + } as const), + template: `{{ $props }}`, + }) + const props = mount(Foo as any, { + props: { + baz: undefined, + qux2: undefined, + }, + global: { + config: { + warnHandler, + }, + }, + }).props() + + expect(props.bar).toBe(false) + expect(props.baz).toBe(undefined) + + expect(warnHandler.mock.calls[0][0]).toBe('Missing required prop: "qux"') + expect(warnHandler.mock.calls[1][0]).toBe( + 'Invalid prop: validation failed for prop "qux2". Expected one of ["a", "b", "c"], got value undefined.' + ) + }) +}) diff --git a/packages/utils-v2/vue/prop.ts b/packages/utils-v2/vue/prop.ts index 99bdf33d37..679a78e87a 100644 --- a/packages/utils-v2/vue/prop.ts +++ b/packages/utils-v2/vue/prop.ts @@ -1,6 +1,7 @@ import { warn } from 'vue' import { fromPairs } from 'lodash-unified' import { isObject } from '../types' +import { hasOwn } from '../objects' import type { ExtractPropTypes, PropType } from 'vue' const wrapperKey = Symbol() @@ -117,7 +118,10 @@ export function buildProp< let allowedValues: unknown[] = [] if (values) { - allowedValues = [...values, defaultValue] + allowedValues = Array.from(values) + if (hasOwn(option, 'default')) { + allowedValues.push(defaultValue) + } valid ||= allowedValues.includes(val) } if (validator) valid ||= validator(val) @@ -138,17 +142,18 @@ export function buildProp< } : undefined - return { + const prop: any = { type: - typeof type === 'object' && - Object.getOwnPropertySymbols(type).includes(wrapperKey) + isObject(type) && Object.getOwnPropertySymbols(type).includes(wrapperKey) ? type[wrapperKey] : type, required: !!required, - default: defaultValue, validator: _validator, [propKey]: true, - } as unknown as BuildPropReturn + } + if (hasOwn(option, 'default')) prop.default = defaultValue + + return prop as BuildPropReturn } type NativePropType = [