Skip to content
/ vue Public
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f6aea2f

Browse files
committedNov 8, 2024
fix(types): backport fix from vuejs/core#8335
1 parent 9e88707 commit f6aea2f

File tree

2 files changed

+72
-21
lines changed

2 files changed

+72
-21
lines changed
 

‎types/test/setup-helpers-test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,40 @@ describe('defineProps w/ runtime declaration', () => {
9898
props2.baz
9999
})
100100

101+
describe('defineProps w/ generic type declaration + withDefaults', <T extends number, TA extends {
102+
a: string
103+
}, TString extends string>() => {
104+
const res = withDefaults(
105+
defineProps<{
106+
n?: number
107+
bool?: boolean
108+
109+
generic1?: T[] | { x: T }
110+
generic2?: { x: T }
111+
generic3?: TString
112+
generic4?: TA
113+
}>(),
114+
{
115+
n: 123,
116+
117+
generic1: () => [123, 33] as T[],
118+
generic2: () => ({ x: 123 } as { x: T }),
119+
120+
generic3: () => 'test' as TString,
121+
generic4: () => ({ a: 'test' } as TA)
122+
}
123+
)
124+
125+
res.n + 1
126+
127+
expectType<T[] | { x: T }>(res.generic1)
128+
expectType<{ x: T }>(res.generic2)
129+
expectType<TString>(res.generic3)
130+
expectType<TA>(res.generic4)
131+
132+
expectType<boolean>(res.bool)
133+
})
134+
101135
describe('defineEmits w/ type declaration', () => {
102136
const emit = defineEmits<(e: 'change') => void>()
103137
emit('change')

‎types/v3-setup-helpers.d.ts

+38-21
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,20 @@ export function defineProps<
4343
PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
4444
>(props: PP): Readonly<ExtractPropTypes<PP>>
4545
// overload 3: typed-based declaration
46-
export function defineProps<TypeProps>(): Readonly<TypeProps>
46+
export function defineProps<TypeProps>(): DefineProps<
47+
TypeProps,
48+
BooleanKey<TypeProps>
49+
>
50+
51+
type DefineProps<T, BKeys extends keyof T> = Readonly<T> & {
52+
readonly [K in BKeys]-?: boolean
53+
}
54+
55+
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
56+
? [T[K]] extends [boolean | undefined]
57+
? K
58+
: never
59+
: never
4760

4861
/**
4962
* Vue `<script setup>` compiler macro for declaring a component's emitted
@@ -96,26 +109,26 @@ export function defineExpose<
96109
type NotUndefined<T> = T extends undefined ? never : T
97110

98111
type InferDefaults<T> = {
99-
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
112+
[K in keyof T]?: InferDefault<T, T[K]>
100113
}
101114

102-
type InferDefault<P, T> = T extends
103-
| null
104-
| number
105-
| string
106-
| boolean
107-
| symbol
108-
| Function
109-
? T | ((props: P) => T)
110-
: (props: P) => T
115+
type NativeType = null | number | string | boolean | symbol | Function
111116

112-
type PropsWithDefaults<Base, Defaults> = Base & {
113-
[K in keyof Defaults]: K extends keyof Base
114-
? Defaults[K] extends undefined
115-
? Base[K]
116-
: NotUndefined<Base[K]>
117-
: never
118-
}
117+
type InferDefault<P, T> =
118+
| ((props: P) => T & {})
119+
| (T extends NativeType ? T : never)
120+
121+
type PropsWithDefaults<
122+
T,
123+
Defaults extends InferDefaults<T>,
124+
BKeys extends keyof T
125+
> = Omit<T, keyof Defaults> & {
126+
[K in keyof Defaults]-?: K extends keyof T
127+
? Defaults[K] extends undefined
128+
? T[K]
129+
: NotUndefined<T[K]>
130+
: never
131+
} & { readonly [K in BKeys]-?: boolean }
119132

120133
/**
121134
* Vue `<script setup>` compiler macro for providing props default values when
@@ -135,10 +148,14 @@ type PropsWithDefaults<Base, Defaults> = Base & {
135148
* This is only usable inside `<script setup>`, is compiled away in the output
136149
* and should **not** be actually called at runtime.
137150
*/
138-
export function withDefaults<Props, Defaults extends InferDefaults<Props>>(
139-
props: Props,
151+
export function withDefaults<
152+
T,
153+
BKeys extends keyof T,
154+
Defaults extends InferDefaults<T>
155+
>(
156+
props: DefineProps<T, BKeys>,
140157
defaults: Defaults
141-
): PropsWithDefaults<Props, Defaults>
158+
): PropsWithDefaults<T, Defaults, BKeys>
142159

143160
// make them global
144161
type _defineProps = typeof defineProps

0 commit comments

Comments
 (0)
Please sign in to comment.