From: pikax Date: Mon, 13 Apr 2020 17:32:14 +0000 (+0100) Subject: Merge remote-tracking branch 'github/master' into changing_unwrap_ref X-Git-Tag: v3.0.0-alpha.13~2^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a66b7b60a7219a444519ca0a84d6a3f17c67a7f;p=thirdparty%2Fvuejs%2Fcore.git Merge remote-tracking branch 'github/master' into changing_unwrap_ref --- 6a66b7b60a7219a444519ca0a84d6a3f17c67a7f diff --cc packages/reactivity/src/ref.ts index f129de67e2,05304ad7ef..479b5847b8 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@@ -101,64 -101,18 +101,64 @@@ function toProxyRef true - type BaseTypes = string | number | boolean + type BaseTypes = string | number | boolean | Node | Window -// Recursively unwraps nested value bindings. -export type UnwrapRef = { - cRef: T extends ComputedRef ? UnwrapRef : T - ref: T extends Ref ? UnwrapRef : T - array: T - object: { [K in keyof T]: UnwrapRef } -}[T extends ComputedRef - ? 'cRef' - : T extends Array - ? 'array' - : T extends Ref | Function | CollectionTypes | BaseTypes - ? 'ref' // bail out on types that shouldn't be unwrapped - : T extends object ? 'object' : 'ref'] +// Super simple tuple checker +type Tupple> = T[0] extends T[1] + ? T[1] extends T[2] ? never : true + : true + +export type UnwrapRef = T extends ComputedRef + ? UnwrapRefSimple + : T extends Ref ? UnwrapRefSimple : UnwrapRefSimple + +type UnwrapRefSimple = T extends + | Function + | CollectionTypes + | BaseTypes + | Ref + | Element + ? T + : T extends Array + ? Tupple extends never ? Array : UnwrapTupple + : T extends object ? UnwrappedObject : T + +export type UnwrapTupple = { [P in keyof T]: T[P] } & { + length: number + [Symbol.iterator]: any + [Symbol.unscopables]: any +} + +// 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 } & SymbolExtract diff --cc test-dts/ref.test-d.ts index e0a70d64f9,4f862a0686..a2c717483b --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@@ -1,7 -1,7 +1,7 @@@ import { expectType } from 'tsd' -import { Ref, ref, isRef, unref } from './index' +import { Ref, ref, isRef, unref, UnwrapRef } from './index' - function foo(arg: number | Ref) { + function plainType(arg: number | Ref) { // ref coercing const coerced = ref(arg) expectType>(coerced) @@@ -20,15 -20,28 +20,37 @@@ }) expectType>(nestedRef) expectType<{ foo: number }>(nestedRef.value) + + interface IteratorFoo { + [Symbol.iterator]: any + } + expectType> | Ref>( + ref(null) + ) + + expectType | Ref>(ref(null)) } - foo(1) + plainType(1) + + function bailType(arg: HTMLElement | Ref) { + // ref coercing + const coerced = ref(arg) + expectType>(coerced) + + // isRef as type guard + if (isRef(arg)) { + expectType>(arg) + } + + // ref unwrapping + expectType(unref(arg)) + + // ref inner type should be unwrapped + const nestedRef = ref({ foo: ref(document.createElement('DIV')) }) + + expectType>(nestedRef) + expectType<{ foo: HTMLElement }>(nestedRef.value) + } + const el = document.createElement('DIV') + bailType(el)