diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 485f56462..f129de67e 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -112,7 +112,12 @@ export type UnwrapRef = T extends ComputedRef ? UnwrapRefSimple : T extends Ref ? UnwrapRefSimple : UnwrapRefSimple -type UnwrapRefSimple = T extends Function | CollectionTypes | BaseTypes | Ref +type UnwrapRefSimple = T extends + | Function + | CollectionTypes + | BaseTypes + | Ref + | Element ? T : T extends Array ? Tupple extends never ? Array : UnwrapTupple @@ -124,6 +129,36 @@ export type UnwrapTupple = { [P in keyof T]: T[P] } & { [Symbol.unscopables]: any } -// interface UnwrappedArray extends Array {} +// Extract all known symbols from an object +// when unwrapping Object the symbols are not `in keyof`, this should cover all the +// known symbols +type SymbolExtract = (T extends { [Symbol.asyncIterator]: infer V } + ? { [Symbol.asyncIterator]: V } + : {}) & + (T extends { [Symbol.hasInstance]: infer V } + ? { [Symbol.hasInstance]: V } + : {}) & + (T extends { [Symbol.isConcatSpreadable]: infer V } + ? { [Symbol.isConcatSpreadable]: V } + : {}) & + (T extends { [Symbol.iterator]: infer V } ? { [Symbol.iterator]: V } : {}) & + (T extends { [Symbol.match]: infer V } ? { [Symbol.match]: V } : {}) & + (T extends { [Symbol.matchAll]: infer V } ? { [Symbol.matchAll]: V } : {}) & + (T extends { [Symbol.observable]: infer V } + ? { [Symbol.observable]: V } + : {}) & + (T extends { [Symbol.replace]: infer V } ? { [Symbol.replace]: V } : {}) & + (T extends { [Symbol.search]: infer V } ? { [Symbol.search]: V } : {}) & + (T extends { [Symbol.species]: infer V } ? { [Symbol.species]: V } : {}) & + (T extends { [Symbol.split]: infer V } ? { [Symbol.split]: V } : {}) & + (T extends { [Symbol.toPrimitive]: infer V } + ? { [Symbol.toPrimitive]: V } + : {}) & + (T extends { [Symbol.toStringTag]: infer V } + ? { [Symbol.toStringTag]: V } + : {}) & + (T extends { [Symbol.unscopables]: infer V } + ? { [Symbol.unscopables]: V } + : {}) -type UnwrappedObject = { [P in keyof T]: UnwrapRef } +type UnwrappedObject = { [P in keyof T]: UnwrapRef } & SymbolExtract diff --git a/test-dts/ref.test-d.ts b/test-dts/ref.test-d.ts index d4f072538..e0a70d64f 100644 --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd' -import { Ref, ref, isRef, unref } from './index' +import { Ref, ref, isRef, unref, UnwrapRef } from './index' function foo(arg: number | Ref) { // ref coercing @@ -20,6 +20,15 @@ function foo(arg: number | Ref) { }) expectType>(nestedRef) expectType<{ foo: number }>(nestedRef.value) + + interface IteratorFoo { + [Symbol.iterator]: any + } + expectType> | Ref>( + ref(null) + ) + + expectType | Ref>(ref(null)) } foo(1)