From ef64e45096961dad11fe5ab1b4522bf46a4427af Mon Sep 17 00:00:00 2001 From: Cathrine Vaage Date: Tue, 9 Nov 2021 14:42:31 +0100 Subject: [PATCH 1/2] fix(runtime-core): add InferDefaults handling of array and object union types This fixes an issue where `InferDefaults` fails to handle union types with base types and array or object types. `TS2322: Type 'number' is not assignable to type '((props: Readonly<{ foo: number | number[]; }>) => number | number[]) | undefined'.` would throw for ```ts withDefault( defineProps<{ foo: number | number[] }>(), { foo: 123 }, ) ``` This adds handling of base types and array or object types separately, so that both types can exist in prop type unions. --- packages/runtime-core/src/apiSetupHelpers.ts | 22 +++++++++++++------- test-dts/setupHelpers.test-d.ts | 15 +++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 292b2f42f7a..5af2021ce44 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -126,15 +126,21 @@ export function defineExpose(exposed?: Record) { type NotUndefined = T extends undefined ? never : T +type BasePropTypes = number | string | boolean | symbol | Function + +type IsBasePropType = T extends BasePropTypes ? T : never +type IsNestedPropType = T extends object | Array ? T : never + type InferDefaults = { - [K in keyof T]?: NotUndefined extends - | number - | string - | boolean - | symbol - | Function - ? NotUndefined - : (props: T) => NotUndefined + [K in keyof T]?: + | (IsBasePropType> extends BasePropTypes + ? IsBasePropType> + : never) + | (IsNestedPropType> extends + | object + | Array + ? (props: T) => IsNestedPropType> + : never) } type PropsWithDefaults = Base & diff --git a/test-dts/setupHelpers.test-d.ts b/test-dts/setupHelpers.test-d.ts index 1b4a2ff43ad..155ba337dcf 100644 --- a/test-dts/setupHelpers.test-d.ts +++ b/test-dts/setupHelpers.test-d.ts @@ -45,6 +45,21 @@ describe('defineProps w/ type declaration + withDefaults', () => { res.x.slice() }) +describe('defineProps w/ union type declaration + withDefaults', () => { + withDefaults( + defineProps<{ + union1?: number | number[] | { x: number } + union2?: number | number[] | { x: number } + union3?: number | number[] | { x: number } + }>(), + { + union1: 123, + union2: () => [123], + union3: () => ({ x: 123 }) + } + ) +}) + describe('defineProps w/ runtime declaration', () => { // runtime declaration const props = defineProps({ From 6361af450a11864d968bc6b6e11d5a24251cd5ba Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 14 Nov 2021 22:03:51 -0500 Subject: [PATCH 2/2] Update apiSetupHelpers.ts --- packages/runtime-core/src/apiSetupHelpers.ts | 31 ++++++++------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 5af2021ce44..fc1866af958 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -126,27 +126,22 @@ export function defineExpose(exposed?: Record) { type NotUndefined = T extends undefined ? never : T -type BasePropTypes = number | string | boolean | symbol | Function - -type IsBasePropType = T extends BasePropTypes ? T : never -type IsNestedPropType = T extends object | Array ? T : never - type InferDefaults = { - [K in keyof T]?: - | (IsBasePropType> extends BasePropTypes - ? IsBasePropType> - : never) - | (IsNestedPropType> extends - | object - | Array - ? (props: T) => IsNestedPropType> - : never) + [K in keyof T]?: InferDefault> } -type PropsWithDefaults = Base & - { - [K in keyof Defaults]: K extends keyof Base ? NotUndefined : never - } +type InferDefault = T extends + | number + | string + | boolean + | symbol + | Function + ? T + : (props: P) => T + +type PropsWithDefaults = Base & { + [K in keyof Defaults]: K extends keyof Base ? NotUndefined : never +} /** * Vue `