Tengo la siguiente configuración, donde quiero usar TypeScript para asegurarme de que el usuario solo elija los tipos que están permitidos en la interfaz.
Esto funciona bien si llamo a la clase directamente, pero si uso una función genérica personalizada para devolver la misma función de clase, no funciona y da un error.
¿Alguien puede ayudarme a entender cómo solucionar esto?
export interface IMyInterface { test1: { test1Sub: { test1SubSub: string } }, test2: { test2Sub: { test2SubSub: string } } } export default class MyClass<T> { parentFunction = <A extends keyof T>(app: A) => ( { childFunction: (page: keyof T[A]) => { console.log(app, page) } } ) } // simplified for example export function useMyCustomHook<T> (app: keyof T) { const settings = new MyClass<T>(); return settings.parentFunction(app) } // Works when calling class directly const myClass = new MyClass<IMyInterface>() const parent = myClass.parentFunction('test1') const child = parent.childFunction('test1Sub') // does not work when calling via hook const myHookValue = useMyCustomHook<IMyInterface>('test1') myHookValue.childFunction('test1') // ERROR - Argument of type 'string' is not assignable to parameter of type 'never'.He creado un ejemplo de patio de recreo de esto.
Solo necesita un tipo explícito para el parámetro de la aplicación:
export function useMyCustomHook<T, A extends keyof T>(app: A) { const settings = new MyClass<T>(); return settings.parentFunction(app); } const myHookValue = useMyCustomHook<IMyInterface, "test2">("test2"); myHookValue.childFunction('test2Sub') Esto se debe a que, sin extender keyof T , dentro del alcance de useCustomHook , el parámetro app siempre se tratará como el tipo keyof T más amplio. Cuando lo usa con childFunction que crea una firma de función de:
childFunction: (page: keyof T[keyof T]) => { console.log(app, page) } El tipo keyof T[keyof T] en MyInterface resuelve en una intersección de dos tipos de cadenas literales "test1Sub" y "test2Sub" , que siempre es never .