Skip to content

Commit fe07f70

Browse files
authoredSep 3, 2024··
fix(types/defineModel): allow getter and setter types to be unrelated (#11699)
close #11697
1 parent b1be9bd commit fe07f70

File tree

3 files changed

+80
-25
lines changed

3 files changed

+80
-25
lines changed
 

‎packages-private/dts-test/setupHelpers.test-d.ts

+45
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,51 @@ describe('defineModel', () => {
427427
defineModel<string>({ default: 123 })
428428
// @ts-expect-error unknown props option
429429
defineModel({ foo: 123 })
430+
431+
// unrelated getter and setter types
432+
{
433+
const modelVal = defineModel({
434+
get(_: string[]): string {
435+
return ''
436+
},
437+
set(_: number) {
438+
return 1
439+
},
440+
})
441+
expectType<string | undefined>(modelVal.value)
442+
modelVal.value = 1
443+
modelVal.value = undefined
444+
// @ts-expect-error
445+
modelVal.value = 'foo'
446+
447+
const [modelVal2] = modelVal
448+
expectType<string | undefined>(modelVal2.value)
449+
modelVal2.value = 1
450+
modelVal2.value = undefined
451+
// @ts-expect-error
452+
modelVal.value = 'foo'
453+
454+
const count = defineModel('count', {
455+
get(_: string[]): string {
456+
return ''
457+
},
458+
set(_: number) {
459+
return ''
460+
},
461+
})
462+
expectType<string | undefined>(count.value)
463+
count.value = 1
464+
count.value = undefined
465+
// @ts-expect-error
466+
count.value = 'foo'
467+
468+
const [count2] = count
469+
expectType<string | undefined>(count2.value)
470+
count2.value = 1
471+
count2.value = undefined
472+
// @ts-expect-error
473+
count2.value = 'foo'
474+
}
430475
})
431476

432477
describe('useModel', () => {

‎packages/runtime-core/src/apiSetupHelpers.ts

+28-24
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,15 @@ export function defineSlots<
240240
return null as any
241241
}
242242

243-
export type ModelRef<T, M extends PropertyKey = string> = Ref<T> &
244-
[ModelRef<T, M>, Record<M, true | undefined>]
243+
export type ModelRef<T, M extends PropertyKey = string, G = T, S = T> = Ref<
244+
G,
245+
S
246+
> &
247+
[ModelRef<T, M, G, S>, Record<M, true | undefined>]
245248

246-
export type DefineModelOptions<T = any> = {
247-
get?: (v: T) => any
248-
set?: (v: T) => any
249+
export type DefineModelOptions<T = any, G = T, S = T> = {
250+
get?: (v: T) => G
251+
set?: (v: S) => any
249252
}
250253

251254
/**
@@ -281,27 +284,28 @@ export type DefineModelOptions<T = any> = {
281284
* const count = defineModel<number>('count', { default: 0 })
282285
* ```
283286
*/
284-
export function defineModel<T, M extends PropertyKey = string>(
285-
options: { required: true } & PropOptions<T> & DefineModelOptions<T>,
286-
): ModelRef<T, M>
287-
export function defineModel<T, M extends PropertyKey = string>(
288-
options: { default: any } & PropOptions<T> & DefineModelOptions<T>,
289-
): ModelRef<T, M>
290-
export function defineModel<T, M extends PropertyKey = string>(
291-
options?: PropOptions<T> & DefineModelOptions<T>,
292-
): ModelRef<T | undefined, M>
293-
export function defineModel<T, M extends PropertyKey = string>(
294-
name: string,
295-
options: { required: true } & PropOptions<T> & DefineModelOptions<T>,
296-
): ModelRef<T, M>
297-
export function defineModel<T, M extends PropertyKey = string>(
287+
export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
288+
options: ({ default: any } | { required: true }) &
289+
PropOptions<T> &
290+
DefineModelOptions<T, G, S>,
291+
): ModelRef<T, M, G, S>
292+
293+
export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
294+
options?: PropOptions<T> & DefineModelOptions<T, G, S>,
295+
): ModelRef<T | undefined, M, G | undefined, S | undefined>
296+
297+
export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
298298
name: string,
299-
options: { default: any } & PropOptions<T> & DefineModelOptions<T>,
300-
): ModelRef<T, M>
301-
export function defineModel<T, M extends PropertyKey = string>(
299+
options: ({ default: any } | { required: true }) &
300+
PropOptions<T> &
301+
DefineModelOptions<T, G, S>,
302+
): ModelRef<T, M, G, S>
303+
304+
export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
302305
name: string,
303-
options?: PropOptions<T> & DefineModelOptions<T>,
304-
): ModelRef<T | undefined, M>
306+
options?: PropOptions<T> & DefineModelOptions<T, G, S>,
307+
): ModelRef<T | undefined, M, G | undefined, S | undefined>
308+
305309
export function defineModel(): any {
306310
if (__DEV__) {
307311
warnRuntimeUsage('defineModel')

‎packages/runtime-core/src/helpers/useModel.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ export function useModel<
1010
M extends PropertyKey,
1111
T extends Record<string, any>,
1212
K extends keyof T,
13-
>(props: T, name: K, options?: DefineModelOptions<T[K]>): ModelRef<T[K], M>
13+
G = T[K],
14+
S = T[K],
15+
>(
16+
props: T,
17+
name: K,
18+
options?: DefineModelOptions<T[K], G, S>,
19+
): ModelRef<T[K], M, G, S>
1420
export function useModel(
1521
props: Record<string, any>,
1622
name: string,

0 commit comments

Comments
 (0)
Please sign in to comment.