Skip to content

Commit 815bfcf

Browse files
committed
fix(types): fix ref macro types
fix #4499
1 parent 5852cc8 commit 815bfcf

File tree

4 files changed

+99
-28
lines changed

4 files changed

+99
-28
lines changed

packages/reactivity/src/computed.ts

+3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import { isFunction, NOOP } from '@vue/shared'
44
import { ReactiveFlags, toRaw } from './reactive'
55
import { Dep } from './dep'
66

7+
declare const ComoutedRefSymbol: unique symbol
8+
79
export interface ComputedRef<T = any> extends WritableComputedRef<T> {
810
readonly value: T
11+
[ComoutedRefSymbol]: true
912
}
1013

1114
export interface WritableComputedRef<T> extends Ref<T> {

packages/reactivity/src/ref.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ export interface RefUnwrapBailTypes {}
251251
export type ShallowUnwrapRef<T> = {
252252
[K in keyof T]: T[K] extends Ref<infer V>
253253
? V
254-
: T[K] extends Ref<infer V> | undefined // if `V` is `unknown` that means it does not extend `Ref` and is undefined
254+
: // if `V` is `unknown` that means it does not extend `Ref` and is undefined
255+
T[K] extends Ref<infer V> | undefined
255256
? unknown extends V
256257
? undefined
257258
: V | undefined

packages/vue/ref-macros.d.ts

+37-15
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,66 @@ import {
44
ComputedRef,
55
WritableComputedOptions,
66
DebuggerOptions,
7-
WritableComputedRef,
8-
ShallowUnwrapRef
7+
WritableComputedRef
98
} from '@vue/runtime-dom'
109

11-
declare const RefMarker: unique symbol
12-
type RefValue<T> = T & { [RefMarker]?: any }
10+
declare const RefType: unique symbol
1311

14-
declare const ComputedRefMarker: unique symbol
15-
type ComputedRefValue<T> = T & { [ComputedRefMarker]?: any }
12+
declare const enum RefTypes {
13+
Ref = 1,
14+
ComputedRef = 2,
15+
WritableComputedRef = 3
16+
}
17+
18+
type RefValue<T> = T extends null | undefined
19+
? T
20+
: T & { [RefType]?: RefTypes.Ref }
21+
22+
type ComputedRefValue<T> = T extends null | undefined
23+
? T
24+
: T & { [RefType]?: RefTypes.ComputedRef }
25+
26+
type WritableComputedRefValue<T> = T extends null | undefined
27+
? T
28+
: T & { [RefType]?: RefTypes.WritableComputedRef }
1629

17-
declare const WritableComputedRefMarker: unique symbol
18-
type WritableComputedRefValue<T> = T & { [WritableComputedRefMarker]?: any }
30+
type NormalObject<T extends object> = T & { [RefType]?: never }
1931

2032
/**
2133
* Vue ref transform macro for binding refs as reactive variables.
2234
*/
2335
declare function _$<T>(arg: ComputedRef<T>): ComputedRefValue<T>
2436
declare function _$<T>(arg: WritableComputedRef<T>): WritableComputedRefValue<T>
2537
declare function _$<T>(arg: Ref<T>): RefValue<T>
26-
declare function _$<T extends object>(arg?: T): ShallowUnwrapRef<T>
38+
declare function _$<T extends object>(arg?: T): DestructureRefs<T>
39+
40+
type DestructureRefs<T extends object> = {
41+
[K in keyof T]: T[K] extends ComputedRef<infer V>
42+
? ComputedRefValue<V>
43+
: T[K] extends WritableComputedRef<infer V>
44+
? WritableComputedRefValue<V>
45+
: T[K] extends Ref<infer V>
46+
? RefValue<V>
47+
: T[K]
48+
}
2749

2850
/**
2951
* Vue ref transform macro for accessing underlying refs of reactive varaibles.
3052
*/
53+
declare function _$$<T extends object>(arg: NormalObject<T>): ToRawRefs<T>
54+
declare function _$$<T>(value: RefValue<T>): Ref<T>
3155
declare function _$$<T>(value: ComputedRefValue<T>): ComputedRef<T>
3256
declare function _$$<T>(
3357
value: WritableComputedRefValue<T>
3458
): WritableComputedRef<T>
35-
declare function _$$<T>(value: RefValue<T>): Ref<T>
36-
declare function _$$<T extends object>(arg: T): ToRawRefs<T>
3759

3860
type ToRawRefs<T extends object> = {
39-
[K in keyof T]: T[K] extends ComputedRefValue<infer V>
40-
? ComputedRefValue<V>
61+
[K in keyof T]: T[K] extends RefValue<infer V>
62+
? Ref<V>
63+
: T[K] extends ComputedRefValue<infer V>
64+
? ComputedRef<V>
4165
: T[K] extends WritableComputedRefValue<infer V>
4266
? WritableComputedRef<V>
43-
: T[K] extends RefValue<infer V>
44-
? Ref<V>
4567
: T[K] extends object
4668
? T[K] extends
4769
| Function

test-dts/refTransformMacros.test-d.ts

+57-12
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,55 @@
11
import { WritableComputedRef } from '@vue/reactivity'
2-
import { expectType, ref, Ref, ComputedRef } from './index'
2+
import { expectType, ref, computed, Ref, ComputedRef } from './index'
33
import 'vue/ref-macros'
4+
import { RefType, RefTypes } from 'vue/ref-macros'
45

56
// wrapping refs
7+
68
// normal
9+
let n = $(ref(1))
10+
n = 2
11+
// @ts-expect-error
12+
n = 'foo'
13+
14+
// #4499 nullable
15+
let msg = $(ref<string | null>(null))
16+
msg = 'hello world'
17+
msg = null
18+
expectType<RefTypes.Ref | undefined>(msg![RefType])
19+
720
// computed
21+
let m = $(computed(() => n + 1))
22+
m * 1
23+
// @ts-expect-error
24+
m.slice()
25+
expectType<RefTypes.ComputedRef | undefined>(m[RefType])
26+
827
// writable computed
28+
let wc = $(
29+
computed({
30+
get: () => n + 1,
31+
set: v => (n = v - 1)
32+
})
33+
)
34+
wc = 2
35+
// @ts-expect-error
36+
wc = 'foo'
37+
expectType<RefTypes.WritableComputedRef | undefined>(wc[RefType])
938

1039
// destructure
11-
const { x, y, z } = $(useFoo())
40+
function useFoo() {
41+
let x = $ref(1)
42+
let y = $computed(() => 'hi')
43+
44+
return $$({
45+
x,
46+
y,
47+
z: 123
48+
})
49+
}
50+
51+
const fooRes = useFoo()
52+
const { x, y, z } = $(fooRes)
1253
expectType<number>(x)
1354
expectType<string>(y)
1455
expectType<number>(z)
@@ -39,17 +80,12 @@ expectType<number>(
3980
})
4081
)
4182

42-
function useFoo() {
43-
return {
44-
x: ref(1),
45-
y: ref('hi'),
46-
z: 123
47-
}
48-
}
49-
5083
// $$
51-
expectType<Ref<number>>($$(x))
52-
expectType<Ref<string>>($$(y))
84+
const xRef = $$(x)
85+
expectType<Ref<number>>(xRef)
86+
87+
const yRef = $$(y)
88+
expectType<ComputedRef<string>>(yRef)
5389

5490
const c = $computed(() => 1)
5591
const cRef = $$(c)
@@ -63,3 +99,12 @@ const c2Ref = $$(c2)
6399
expectType<WritableComputedRef<number>>(c2Ref)
64100

65101
// $$ on object
102+
const obj = $$({
103+
n,
104+
m,
105+
wc
106+
})
107+
108+
expectType<Ref<number>>(obj.n)
109+
expectType<ComputedRef<number>>(obj.m)
110+
expectType<WritableComputedRef<number>>(obj.wc)

0 commit comments

Comments
 (0)