diff --git a/packages/dts-test/setupHelpers.test-d.ts b/packages/dts-test/setupHelpers.test-d.ts index feb4085de..96dbb73fd 100644 --- a/packages/dts-test/setupHelpers.test-d.ts +++ b/packages/dts-test/setupHelpers.test-d.ts @@ -19,7 +19,7 @@ describe('defineProps w/ type declaration', () => { const props = defineProps<{ foo: string bool?: boolean - boolAndUndefined: boolean | undefined + boolOrUndefined: boolean | undefined }>() // explicitly declared type should be refined expectType(props.foo) @@ -27,7 +27,7 @@ describe('defineProps w/ type declaration', () => { props.bar expectType(props.bool) - expectType(props.boolAndUndefined) + expectType(props.boolOrUndefined) }) describe('defineProps w/ generics', () => { @@ -52,7 +52,8 @@ describe('defineProps w/ type declaration + withDefaults', () => { y?: string z?: string bool?: boolean - boolAndUndefined: boolean | undefined + boolOrUndefined: boolean | undefined + defaultUndefined?: string }>(), { number: 123, @@ -61,10 +62,14 @@ describe('defineProps w/ type declaration + withDefaults', () => { fn: () => {}, genStr: () => '', y: undefined, - z: 'string' + z: 'string', + defaultUndefined: undefined as string | undefined } ) + // @ts-expect-error + res.number++ + res.number + 1 res.arr.push('hi') res.obj.x @@ -75,12 +80,21 @@ describe('defineProps w/ type declaration + withDefaults', () => { // @ts-expect-error res.y.slice() - expectType(res.x) - expectType(res.y) - expectType(res.z) - - expectType(res.bool) - expectType(res.boolAndUndefined) + type T = { + number: number + arr: string[] + obj: { x: number } + fn: (e: string) => void + genStr: string + x: string | undefined + y: string | undefined + z: string + bool: boolean + boolOrUndefined: boolean + defaultUndefined: string | undefined + } + expectType(res) + expectType({} as T) }) describe('defineProps w/ union type declaration + withDefaults', () => { @@ -127,6 +141,9 @@ describe('defineProps w/ generic type declaration + withDefaults', (res.generic1) expectType<{ x: T }>(res.generic2) expectType(res.generic3) diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 932006670..486842756 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -293,23 +293,31 @@ type InferDefault = | ((props: P) => T & {}) | (T extends NativeType ? T : never) +type NonPartial = { + [K in keyof Required]: T[K] +} + +type UndefinedDefault = Default extends undefined + ? T + : NotUndefined + type PropsWithDefaults< T, Defaults extends InferDefaults, BKeys extends keyof T -> = Omit & { - [K in keyof Defaults]-?: K extends keyof T - ? Defaults[K] extends undefined - ? T[K] - : NotUndefined - : never -} & { - readonly [K in BKeys]-?: K extends keyof Defaults - ? Defaults[K] extends undefined - ? boolean | undefined +> = Readonly< + NonPartial> & { + [K in keyof Defaults]-?: K extends keyof T + ? UndefinedDefault + : never + } & { + [K in BKeys]: K extends keyof Defaults + ? Defaults[K] extends undefined + ? boolean | undefined + : boolean : boolean - : boolean -} + } +> /** * Vue `