Skip to content

Commit

Permalink
fix(types/defineModel): allow getter and setter types to be unrelated (
Browse files Browse the repository at this point in the history
  • Loading branch information
jh-leong authored Sep 3, 2024
1 parent b1be9bd commit fe07f70
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 25 deletions.
45 changes: 45 additions & 0 deletions packages-private/dts-test/setupHelpers.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,51 @@ describe('defineModel', () => {
defineModel<string>({ default: 123 })
// @ts-expect-error unknown props option
defineModel({ foo: 123 })

// unrelated getter and setter types
{
const modelVal = defineModel({
get(_: string[]): string {
return ''
},
set(_: number) {
return 1
},
})
expectType<string | undefined>(modelVal.value)
modelVal.value = 1
modelVal.value = undefined
// @ts-expect-error
modelVal.value = 'foo'

const [modelVal2] = modelVal
expectType<string | undefined>(modelVal2.value)
modelVal2.value = 1
modelVal2.value = undefined
// @ts-expect-error
modelVal.value = 'foo'

const count = defineModel('count', {
get(_: string[]): string {
return ''
},
set(_: number) {
return ''
},
})
expectType<string | undefined>(count.value)
count.value = 1
count.value = undefined
// @ts-expect-error
count.value = 'foo'

const [count2] = count
expectType<string | undefined>(count2.value)
count2.value = 1
count2.value = undefined
// @ts-expect-error
count2.value = 'foo'
}
})

describe('useModel', () => {
Expand Down
52 changes: 28 additions & 24 deletions packages/runtime-core/src/apiSetupHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,15 @@ export function defineSlots<
return null as any
}

export type ModelRef<T, M extends PropertyKey = string> = Ref<T> &
[ModelRef<T, M>, Record<M, true | undefined>]
export type ModelRef<T, M extends PropertyKey = string, G = T, S = T> = Ref<
G,
S
> &
[ModelRef<T, M, G, S>, Record<M, true | undefined>]

export type DefineModelOptions<T = any> = {
get?: (v: T) => any
set?: (v: T) => any
export type DefineModelOptions<T = any, G = T, S = T> = {
get?: (v: T) => G
set?: (v: S) => any
}

/**
Expand Down Expand Up @@ -281,27 +284,28 @@ export type DefineModelOptions<T = any> = {
* const count = defineModel<number>('count', { default: 0 })
* ```
*/
export function defineModel<T, M extends PropertyKey = string>(
options: { required: true } & PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T, M>
export function defineModel<T, M extends PropertyKey = string>(
options: { default: any } & PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T, M>
export function defineModel<T, M extends PropertyKey = string>(
options?: PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T | undefined, M>
export function defineModel<T, M extends PropertyKey = string>(
name: string,
options: { required: true } & PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T, M>
export function defineModel<T, M extends PropertyKey = string>(
export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
options: ({ default: any } | { required: true }) &
PropOptions<T> &
DefineModelOptions<T, G, S>,
): ModelRef<T, M, G, S>

export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
options?: PropOptions<T> & DefineModelOptions<T, G, S>,
): ModelRef<T | undefined, M, G | undefined, S | undefined>

export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
name: string,
options: { default: any } & PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T, M>
export function defineModel<T, M extends PropertyKey = string>(
options: ({ default: any } | { required: true }) &
PropOptions<T> &
DefineModelOptions<T, G, S>,
): ModelRef<T, M, G, S>

export function defineModel<T, M extends PropertyKey = string, G = T, S = T>(
name: string,
options?: PropOptions<T> & DefineModelOptions<T>,
): ModelRef<T | undefined, M>
options?: PropOptions<T> & DefineModelOptions<T, G, S>,
): ModelRef<T | undefined, M, G | undefined, S | undefined>

export function defineModel(): any {
if (__DEV__) {
warnRuntimeUsage('defineModel')
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-core/src/helpers/useModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ export function useModel<
M extends PropertyKey,
T extends Record<string, any>,
K extends keyof T,
>(props: T, name: K, options?: DefineModelOptions<T[K]>): ModelRef<T[K], M>
G = T[K],
S = T[K],
>(
props: T,
name: K,
options?: DefineModelOptions<T[K], G, S>,
): ModelRef<T[K], M, G, S>
export function useModel(
props: Record<string, any>,
name: string,
Expand Down

0 comments on commit fe07f70

Please sign in to comment.