? UnwrapRefSimple<V>
: T extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<T>
-type UnwrapRefSimple<T> = T extends Function | CollectionTypes | BaseTypes | Ref
+type UnwrapRefSimple<T> = T extends
+ | Function
+ | CollectionTypes
+ | BaseTypes
+ | Ref
+ | Element
? T
: T extends Array<infer V>
? Tupple<T> extends never ? Array<V> : UnwrapTupple<T>
[Symbol.unscopables]: any
}
-// interface UnwrappedArray<T> extends Array<T> {}
-
-type UnwrappedObject<T> = { [P in keyof T]: UnwrapRef<T[P]> }
+// 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> = (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<T> = { [P in keyof T]: UnwrapRef<T[P]> } & SymbolExtract<T>
import { expectType } from 'tsd'
-import { Ref, ref, isRef, unref } from './index'
+import { Ref, ref, isRef, unref, UnwrapRef } from './index'
function foo(arg: number | Ref<number>) {
// ref coercing
})
expectType<Ref<{ foo: number }>>(nestedRef)
expectType<{ foo: number }>(nestedRef.value)
+
+ interface IteratorFoo {
+ [Symbol.iterator]: any
+ }
+ expectType<Ref<UnwrapRef<IteratorFoo>> | Ref<null>>(
+ ref<IteratorFoo | null>(null)
+ )
+
+ expectType<Ref<HTMLElement> | Ref<null>>(ref<HTMLElement | null>(null))
}
foo(1)