| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import { defineReactive } from 'core/observer/index'
- import { isReactive, type ShallowReactiveMarker } from './reactive'
- import type { IfAny } from 'typescript/utils'
- import Dep from 'core/observer/dep'
- import { warn, isArray } from 'core/util'
- declare const RefSymbol: unique symbol
- export declare const RawSymbol: unique symbol
- export interface Ref<T = any> {
- value: T
- /**
- * Type differentiator only.
- * We need this to be in public d.ts but don't want it to show up in IDE
- * autocomplete, so we use a private Symbol instead.
- */
- [RefSymbol]: true
- /**
- * @private
- */
- dep?: Dep
- }
- export function isRef<T>(r: Ref<T> | unknown): r is Ref<T>
- export function isRef(r: any): r is Ref {
- return !!(r && r.__v_isRef === true)
- }
- export function ref<T extends object>(
- value: T
- ): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
- export function ref<T>(value: T): Ref<UnwrapRef<T>>
- export function ref<T = any>(): Ref<T | undefined>
- export function ref(value?: unknown) {
- return createRef(value, false)
- }
- declare const ShallowRefMarker: unique symbol
- export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
- export function shallowRef<T extends object>(
- value: T
- ): T extends Ref ? T : ShallowRef<T>
- export function shallowRef<T>(value: T): ShallowRef<T>
- export function shallowRef<T = any>(): ShallowRef<T | undefined>
- export function shallowRef(value?: unknown) {
- return createRef(value, true)
- }
- function createRef(rawValue: unknown, shallow: boolean) {
- if (isRef(rawValue)) {
- return rawValue
- }
- const ref: any = { __v_isRef: true, __v_isShallow: shallow }
- ref.dep = defineReactive(ref, 'value', rawValue, null, shallow)
- return ref
- }
- export function triggerRef(ref: Ref) {
- if (__DEV__ && !ref.dep) {
- warn(`received object is not a triggerable ref.`)
- }
- ref.dep && ref.dep.notify()
- }
- export function unref<T>(ref: T | Ref<T>): T {
- return isRef(ref) ? (ref.value as any) : ref
- }
- export type CustomRefFactory<T> = (
- track: () => void,
- trigger: () => void
- ) => {
- get: () => T
- set: (value: T) => void
- }
- class CustomRefImpl<T> {
- public dep = new Dep()
- private readonly _get: ReturnType<CustomRefFactory<T>>['get']
- private readonly _set: ReturnType<CustomRefFactory<T>>['set']
- public readonly __v_isRef = true
- constructor(factory: CustomRefFactory<T>) {
- const { get, set } = factory(
- () => this.dep.depend(),
- () => this.dep.notify()
- )
- this._get = get
- this._set = set
- }
- get value() {
- return this._get()
- }
- set value(newVal) {
- this._set(newVal)
- }
- }
- export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
- return new CustomRefImpl(factory) as any
- }
- export type ToRefs<T = any> = {
- [K in keyof T]: ToRef<T[K]>
- }
- export function toRefs<T extends object>(object: T): ToRefs<T> {
- if (__DEV__ && !isReactive(object)) {
- warn(`toRefs() expects a reactive object but received a plain one.`)
- }
- const ret: any = isArray(object) ? new Array(object.length) : {}
- for (const key in object) {
- ret[key] = toRef(object, key)
- }
- return ret
- }
- class ObjectRefImpl<T extends object, K extends keyof T> {
- public readonly __v_isRef = true
- constructor(
- private readonly _object: T,
- private readonly _key: K,
- private readonly _defaultValue?: T[K]
- ) {}
- get value() {
- const val = this._object[this._key]
- return val === undefined ? (this._defaultValue as T[K]) : val
- }
- set value(newVal) {
- this._object[this._key] = newVal
- }
- }
- export type ToRef<T> = IfAny<T, Ref<T>, [T] extends [Ref] ? T : Ref<T>>
- export function toRef<T extends object, K extends keyof T>(
- object: T,
- key: K
- ): ToRef<T[K]>
- export function toRef<T extends object, K extends keyof T>(
- object: T,
- key: K,
- defaultValue: T[K]
- ): ToRef<Exclude<T[K], undefined>>
- export function toRef<T extends object, K extends keyof T>(
- object: T,
- key: K,
- defaultValue?: T[K]
- ): ToRef<T[K]> {
- const val = object[key]
- return isRef(val)
- ? val
- : (new ObjectRefImpl(object, key, defaultValue) as any)
- }
- /**
- * This is a special exported interface for other packages to declare
- * additional types that should bail out for ref unwrapping. For example
- * \@vue/runtime-dom can declare it like so in its d.ts:
- *
- * ``` ts
- * declare module 'vue' {
- * export interface RefUnwrapBailTypes {
- * runtimeDOMBailTypes: Node | Window
- * }
- * }
- * ```
- *
- * Note that api-extractor somehow refuses to include `declare module`
- * augmentations in its generated d.ts, so we have to manually append them
- * to the final generated d.ts in our build process.
- */
- export interface RefUnwrapBailTypes {}
- export type ShallowUnwrapRef<T> = {
- [K in keyof T]: T[K] extends Ref<infer V>
- ? V
- : // if `V` is `unknown` that means it does not extend `Ref` and is undefined
- T[K] extends Ref<infer V> | undefined
- ? unknown extends V
- ? undefined
- : V | undefined
- : T[K]
- }
- export type UnwrapRef<T> = T extends ShallowRef<infer V>
- ? V
- : T extends Ref<infer V>
- ? UnwrapRefSimple<V>
- : UnwrapRefSimple<T>
- type BaseTypes = string | number | boolean
- type CollectionTypes = IterableCollections | WeakCollections
- type IterableCollections = Map<any, any> | Set<any>
- type WeakCollections = WeakMap<any, any> | WeakSet<any>
- export type UnwrapRefSimple<T> = T extends
- | Function
- | CollectionTypes
- | BaseTypes
- | Ref
- | RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
- | { [RawSymbol]?: true }
- ? T
- : T extends Array<any>
- ? { [K in keyof T]: UnwrapRefSimple<T[K]> }
- : T extends object & { [ShallowReactiveMarker]?: never }
- ? {
- [P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]>
- }
- : T
|