From e267e0d392970665608294c27d5bd3ffbe0579c9 Mon Sep 17 00:00:00 2001 From: Cody Bennett Date: Thu, 16 Jan 2025 05:41:57 -0600 Subject: [PATCH] fix(useLoader): allow mutable upstream input types --- packages/fiber/src/core/hooks.tsx | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/fiber/src/core/hooks.tsx b/packages/fiber/src/core/hooks.tsx index 811d9699cc..cc93a577d2 100644 --- a/packages/fiber/src/core/hooks.tsx +++ b/packages/fiber/src/core/hooks.tsx @@ -61,10 +61,12 @@ export function useGraph(object: THREE.Object3D): ObjectMap { return React.useMemo(() => buildGraph(object), [object]) } -type LoaderInstance | ConstructorRepresentation>> = - T extends ConstructorRepresentation> ? InstanceType : T +type LoaderLike = THREE.Loader> -export type LoaderResult | ConstructorRepresentation>> = Awaited< +type LoaderInstance> = + T extends ConstructorRepresentation ? InstanceType : T + +export type LoaderResult> = Awaited< ReturnType['loadAsync']> > extends infer R ? R extends { scene: THREE.Object3D } @@ -72,21 +74,23 @@ export type LoaderResult | ConstructorRepresentation : R : never -export type Extensions | ConstructorRepresentation>> = ( +export type Extensions> = ( loader: LoaderInstance, ) => void -const memoizedLoaders = new WeakMap>, THREE.Loader>() +const memoizedLoaders = new WeakMap, LoaderLike>() -const isConstructor = (value: unknown): value is ConstructorRepresentation> => +const isConstructor = ( + value: unknown, +): value is ConstructorRepresentation> => typeof value === 'function' && value?.prototype?.constructor === value -function loadingFn | ConstructorRepresentation>>( +function loadingFn>>( extensions?: Extensions, onProgress?: (event: ProgressEvent) => void, ) { return function (Proto: L, ...input: string[]) { - let loader: THREE.Loader + let loader: LoaderLike // Construct and cache loader if constructor was passed if (isConstructor(Proto)) { @@ -131,7 +135,7 @@ function loadingFn | ConstructorRepresentation | ConstructorRepresentation>, + L extends LoaderLike | ConstructorRepresentation, >(loader: L, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent) => void) { // Use suspense to load async assets const keys = (Array.isArray(input) ? input : [input]) as string[] @@ -146,7 +150,7 @@ export function useLoader< useLoader.preload = function < T, U extends string | string[] | string[][], - L extends THREE.Loader | ConstructorRepresentation>, + L extends LoaderLike | ConstructorRepresentation, >(loader: L, input: U, extensions?: Extensions): void { const keys = (Array.isArray(input) ? input : [input]) as string[] return preload(loadingFn(extensions), [loader, ...keys]) @@ -158,7 +162,7 @@ useLoader.preload = function < useLoader.clear = function < T, U extends string | string[] | string[][], - L extends THREE.Loader | ConstructorRepresentation>, + L extends LoaderLike | ConstructorRepresentation, >(loader: L, input: U): void { const keys = (Array.isArray(input) ? input : [input]) as string[] return clear([loader, ...keys])