diff --git a/.changeset/dirty-radios-laugh.md b/.changeset/dirty-radios-laugh.md new file mode 100644 index 00000000..931dfd08 --- /dev/null +++ b/.changeset/dirty-radios-laugh.md @@ -0,0 +1,5 @@ +--- +"leva": patch +--- + +fix: using get with items with onChange is now correctly typed diff --git a/packages/leva/src/types/public.test.ts b/packages/leva/src/types/public.test.ts index ca6e9777..25805806 100644 --- a/packages/leva/src/types/public.test.ts +++ b/packages/leva/src/types/public.test.ts @@ -137,6 +137,52 @@ expectType<{ }) ) +// folders with onChange should exclude transient items from return type but include them in get function +expectType<{ a1: number }>( + useControls({ + a: folder({ + a1: 1, + a2: { value: 'transient', onChange: () => {} }, + }), + }) +) + +// test that get function includes transient items in folders +expectType< + [ + { a1: number }, + (value: { a1?: number; a2?: string }) => void, + (path: T) => { a1: number; a2: string }[T] + ] +>( + useControls(() => ({ + a: folder({ + a1: 1, + a2: { value: 'transient', onChange: () => {} }, + }), + })) +) + +// nested folders with onChange +expectType< + [ + { a1: number }, + (value: { a1?: number; b1?: number; b2?: string }) => void, + (path: T) => { a1: number; b1: number; b2: string }[T] + ] +>( + useControls(() => ({ + a: folder({ + a1: 1, + a2: { value: 'transient', onChange: () => {} }, + b: folder({ + b1: { value: 10 }, + b2: { value: 'also transient', onChange: () => {} }, + }), + }), + })) +) + /** * custom plugins */ diff --git a/packages/leva/src/types/public.ts b/packages/leva/src/types/public.ts index 254b678d..975dd28a 100644 --- a/packages/leva/src/types/public.ts +++ b/packages/leva/src/types/public.ts @@ -241,7 +241,11 @@ type Join = EndLeaf extends Leaf2 type Tree = { // if it's a folder we run the type check on it's schema key - 0: Leaf extends { schema: infer Schema } ? { [Key in keyof Schema]: Join } : never + // recursively process each item in the folder with Tree to propagate IncludeTransient flag, + // which ensures items with onChange inside folders are correctly handled for the get function + 0: Leaf extends { schema: infer Schema } + ? { [Key in keyof Schema]: Join> }[keyof Schema] + : never 1: never // if the leaf is an object, we run the type check on each of its keys 2: {