wip: test + typing for value
This commit is contained in:
@@ -24,11 +24,13 @@ import {
|
||||
DebuggerEvent
|
||||
} from './effect'
|
||||
|
||||
import { UnwrapBindings } from './value'
|
||||
|
||||
export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
|
||||
export { OperationTypes } from './operations'
|
||||
export { computed, ComputedValue } from './computed'
|
||||
export { lock, unlock } from './lock'
|
||||
export { value, isValue, Value } from './value'
|
||||
export { value, isValue, Value, UnwrapBindings } from './value'
|
||||
|
||||
const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
|
||||
const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
|
||||
@@ -42,7 +44,7 @@ const canObserve = (value: any): boolean => {
|
||||
)
|
||||
}
|
||||
|
||||
type identity = <T>(target?: T) => T
|
||||
type ObservableFactory = <T>(target?: T) => UnwrapBindings<T>
|
||||
|
||||
export const observable = ((target: any = {}): any => {
|
||||
// if trying to observe an immutable proxy, return the immutable version.
|
||||
@@ -60,7 +62,7 @@ export const observable = ((target: any = {}): any => {
|
||||
mutableHandlers,
|
||||
mutableCollectionHandlers
|
||||
)
|
||||
}) as identity
|
||||
}) as ObservableFactory
|
||||
|
||||
export const immutable = ((target: any = {}): any => {
|
||||
// value is a mutable observable, retrive its original and return
|
||||
@@ -75,7 +77,7 @@ export const immutable = ((target: any = {}): any => {
|
||||
immutableHandlers,
|
||||
immutableCollectionHandlers
|
||||
)
|
||||
}) as identity
|
||||
}) as ObservableFactory
|
||||
|
||||
function createObservable(
|
||||
target: any,
|
||||
|
||||
@@ -9,6 +9,62 @@ export interface Value<T> {
|
||||
value: T
|
||||
}
|
||||
|
||||
type UnwrapValue<T, U = T> = T extends Value<infer V> ? V : T extends {} ? U : T
|
||||
|
||||
// A utility type that recursively unwraps value bindings nested inside an
|
||||
// observable object. Unfortunately TS cannot do recursive types, but this
|
||||
// should be enough for practical use cases...
|
||||
export type UnwrapBindings<T> = {
|
||||
[key in keyof T]: UnwrapValue<
|
||||
T[key],
|
||||
{
|
||||
[k2 in keyof T[key]]: UnwrapValue<
|
||||
T[key][k2],
|
||||
{
|
||||
[k3 in keyof T[key][k2]]: UnwrapValue<
|
||||
T[key][k2][k3],
|
||||
{
|
||||
[k4 in keyof T[key][k2][k3]]: UnwrapValue<
|
||||
T[key][k2][k3][k4],
|
||||
{
|
||||
[k5 in keyof T[key][k2][k3][k4]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5],
|
||||
{
|
||||
[k6 in keyof T[key][k2][k3][k4][k5]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5][k6],
|
||||
{
|
||||
[k7 in keyof T[key][k2][k3][k4][k5][k6]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5][k6][k7],
|
||||
{
|
||||
[k8 in keyof T[key][k2][k3][k4][k5][k6][k7]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5][k6][k7][k8],
|
||||
{
|
||||
[k9 in keyof T[key][k2][k3][k4][k5][k6][k7][k8]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5][k6][k7][k8][k9],
|
||||
{
|
||||
[k10 in keyof T[key][k2][k3][k4][k5][k6][k7][k8][k9]]: UnwrapValue<
|
||||
T[key][k2][k3][k4][k5][k6][k7][k8][k9][k10]
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
>
|
||||
}
|
||||
|
||||
const convert = (val: any): any => (isObject(val) ? observable(val) : val)
|
||||
|
||||
export function value<T>(raw: T): Value<T> {
|
||||
|
||||
Reference in New Issue
Block a user