Skip to content

Commit e816812

Browse files
authoredOct 26, 2022
fix(types): should unwrap tuple correctly (#3820)
fix #3819
1 parent 09bb3e9 commit e816812

File tree

2 files changed

+78
-70
lines changed

2 files changed

+78
-70
lines changed
 

‎packages/reactivity/src/ref.ts

+5-8
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,10 @@ export interface RefUnwrapBailTypes {}
280280

281281
export type ShallowUnwrapRef<T> = {
282282
[K in keyof T]: T[K] extends Ref<infer V>
283-
? V
284-
: // if `V` is `unknown` that means it does not extend `Ref` and is undefined
285-
T[K] extends Ref<infer V> | undefined
286-
? unknown extends V
287-
? undefined
288-
: V | undefined
289-
: T[K]
283+
? V // if `V` is `unknown` that means it does not extend `Ref` and is undefined
284+
: T[K] extends Ref<infer V> | undefined
285+
? unknown extends V ? undefined : V | undefined
286+
: T[K]
290287
}
291288

292289
export type UnwrapRef<T> = T extends ShallowRef<infer V>
@@ -303,7 +300,7 @@ export type UnwrapRefSimple<T> = T extends
303300
| RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
304301
| { [RawSymbol]?: true }
305302
? T
306-
: T extends Array<any>
303+
: T extends ReadonlyArray<any>
307304
? { [K in keyof T]: UnwrapRefSimple<T[K]> }
308305
: T extends object & { [ShallowReactiveMarker]?: never }
309306
? {

‎test-dts/reactivity.test-d.ts

+73-62
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,73 @@
1-
import {
2-
ref,
3-
readonly,
4-
shallowReadonly,
5-
describe,
6-
expectError,
7-
expectType,
8-
Ref,
9-
reactive,
10-
markRaw
11-
} from './index'
12-
13-
describe('should support DeepReadonly', () => {
14-
const r = readonly({ obj: { k: 'v' } })
15-
// @ts-expect-error
16-
expectError((r.obj = {}))
17-
// @ts-expect-error
18-
expectError((r.obj.k = 'x'))
19-
})
20-
21-
// #4180
22-
describe('readonly ref', () => {
23-
const r = readonly(ref({ count: 1 }))
24-
expectType<Ref>(r)
25-
})
26-
27-
describe('should support markRaw', () => {
28-
class Test<T> {
29-
item = {} as Ref<T>
30-
}
31-
const test = new Test<number>()
32-
const plain = {
33-
ref: ref(1)
34-
}
35-
36-
const r = reactive({
37-
class: {
38-
raw: markRaw(test),
39-
reactive: test
40-
},
41-
plain: {
42-
raw: markRaw(plain),
43-
reactive: plain
44-
}
45-
})
46-
47-
expectType<Test<number>>(r.class.raw)
48-
// @ts-expect-error it should unwrap
49-
expectType<Test<number>>(r.class.reactive)
50-
51-
expectType<Ref<number>>(r.plain.raw.ref)
52-
// @ts-expect-error it should unwrap
53-
expectType<Ref<number>>(r.plain.reactive.ref)
54-
})
55-
56-
describe('shallowReadonly ref unwrap', () => {
57-
const r = shallowReadonly({ count: { n: ref(1) } })
58-
// @ts-expect-error
59-
r.count = 2
60-
expectType<Ref>(r.count.n)
61-
r.count.n.value = 123
62-
})
1+
import {
2+
ref,
3+
readonly,
4+
shallowReadonly,
5+
describe,
6+
expectError,
7+
expectType,
8+
Ref,
9+
reactive,
10+
markRaw
11+
} from './index'
12+
13+
describe('should support DeepReadonly', () => {
14+
const r = readonly({ obj: { k: 'v' } })
15+
// @ts-expect-error
16+
expectError((r.obj = {}))
17+
// @ts-expect-error
18+
expectError((r.obj.k = 'x'))
19+
})
20+
21+
// #4180
22+
describe('readonly ref', () => {
23+
const r = readonly(ref({ count: 1 }))
24+
expectType<Ref>(r)
25+
})
26+
27+
describe('should support markRaw', () => {
28+
class Test<T> {
29+
item = {} as Ref<T>
30+
}
31+
const test = new Test<number>()
32+
const plain = {
33+
ref: ref(1)
34+
}
35+
36+
const r = reactive({
37+
class: {
38+
raw: markRaw(test),
39+
reactive: test
40+
},
41+
plain: {
42+
raw: markRaw(plain),
43+
reactive: plain
44+
}
45+
})
46+
47+
expectType<Test<number>>(r.class.raw)
48+
// @ts-expect-error it should unwrap
49+
expectType<Test<number>>(r.class.reactive)
50+
51+
expectType<Ref<number>>(r.plain.raw.ref)
52+
// @ts-expect-error it should unwrap
53+
expectType<Ref<number>>(r.plain.reactive.ref)
54+
})
55+
56+
describe('shallowReadonly ref unwrap', () => {
57+
const r = shallowReadonly({ count: { n: ref(1) } })
58+
// @ts-expect-error
59+
r.count = 2
60+
expectType<Ref>(r.count.n)
61+
r.count.n.value = 123
62+
})
63+
64+
// #3819
65+
describe('should unwrap tuple correctly', () => {
66+
const readonlyTuple = [ref(0)] as const
67+
const reactiveReadonlyTuple = reactive(readonlyTuple)
68+
expectType<Ref<number>>(reactiveReadonlyTuple[0])
69+
70+
const tuple: [Ref<number>] = [ref(0)]
71+
const reactiveTuple = reactive(tuple)
72+
expectType<Ref<number>>(reactiveTuple[0])
73+
})

0 commit comments

Comments
 (0)
Please sign in to comment.