From 04b2fad038da501232297e29ad2371a63a26c8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 25 Apr 2025 07:40:21 +0200 Subject: [PATCH] PropertyPath --- .../types/{SearchPaths.ts => PropertyPath.ts} | 24 ++++++++++++------- packages/reffuse/src/types/index.ts | 1 + 2 files changed, 16 insertions(+), 9 deletions(-) rename packages/reffuse/src/types/{SearchPaths.ts => PropertyPath.ts} (82%) diff --git a/packages/reffuse/src/types/SearchPaths.ts b/packages/reffuse/src/types/PropertyPath.ts similarity index 82% rename from packages/reffuse/src/types/SearchPaths.ts rename to packages/reffuse/src/types/PropertyPath.ts index 806f1be..6e76188 100644 --- a/packages/reffuse/src/types/SearchPaths.ts +++ b/packages/reffuse/src/types/PropertyPath.ts @@ -1,16 +1,13 @@ import { Array, Option, Predicate, Schema } from "effect" -export type Key = string | number | symbol -export type Path = readonly Key[] - export type Paths = [] | ( T extends readonly any[] ? ArrayPaths : T extends object ? ObjectPaths : never ) -type ArrayPaths = { +export type ArrayPaths = { [K in keyof T as K extends number ? K : never]: | [K] | [K, ...Paths] @@ -18,7 +15,7 @@ type ArrayPaths = { ? O[keyof O] : never -type ObjectPaths = { +export type ObjectPaths = { [K in keyof T as K extends string | number | symbol ? K : never]: | [K] | [K, ...Paths] @@ -36,12 +33,21 @@ export type ValueFromPath = P extends [infer Head, ...infer : never : T +export type AnyKey = string | number | symbol +export type AnyPath = readonly AnyKey[] -export const unsafeGet = >(parent: T, path: P): ValueFromPath => ( + +export const unsafeGet = >( + parent: T, + path: P, +): ValueFromPath => ( path.reduce((acc: any, key: any) => acc?.[key], parent) ) -export const get = >(parent: T, path: P): Option.Option> => path.reduce( +export const get = >( + parent: T, + path: P, +): Option.Option> => path.reduce( (acc: Option.Option, key: any): Option.Option => Option.isSome(acc) ? Predicate.hasProperty(acc.value, key) ? Option.some(acc.value[key]) @@ -57,13 +63,13 @@ export const immutableSet = >( path: P, value: ValueFromPath, ): Option.Option => { - const key = Array.head(path as Path) + const key = Array.head(path as AnyPath) if (Option.isNone(key)) return Option.some(value as T) if (!Predicate.hasProperty(parent, key.value)) return Option.none() - const child = immutableSet(parent[key.value], Option.getOrThrow(Array.tail(path as Path)), value) + const child = immutableSet(parent[key.value], Option.getOrThrow(Array.tail(path as AnyPath)), value) if (Option.isNone(child)) return child diff --git a/packages/reffuse/src/types/index.ts b/packages/reffuse/src/types/index.ts index ec93c5f..e8b2633 100644 --- a/packages/reffuse/src/types/index.ts +++ b/packages/reffuse/src/types/index.ts @@ -1,2 +1,3 @@ +export * as PropertyPath from "./PropertyPath.js" export * as SetStateAction from "./SetStateAction.js" export * as SubscriptionSubRef from "./SubscriptionSubRef.js"