Skip to content

Commit

Permalink
types: add symbolExtract to extract all known symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
pikax committed Apr 12, 2020
1 parent ab9add4 commit c20d8af
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
43 changes: 39 additions & 4 deletions packages/reactivity/src/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@ export type UnwrapRef<T> = T extends ComputedRef<infer V>
? 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>
Expand All @@ -124,6 +129,36 @@ export type UnwrapTupple<T> = { [P in keyof T]: T[P] } & {
[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>
11 changes: 10 additions & 1 deletion test-dts/ref.test-d.ts
Original file line number Diff line number Diff line change
@@ -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<number>) {
// ref coercing
Expand All @@ -20,6 +20,15 @@ function foo(arg: number | Ref<number>) {
})
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)

0 comments on commit c20d8af

Please sign in to comment.