Me gustaría crear un tipo que pueda ser un valor ( string , bool , number , ...), función u observable y luego poder acceder a su valor en la plantilla del componente.
La motivación es crear una API flexible para las propiedades de entrada del componente, donde el usuario puede proporcionar la entrada como el tipo que más le convenga (valor, función u observable) y el componente debe ser lo suficientemente "inteligente" para representar el valor de acuerdo con su tipo.
Tener un tipo común para el valor y la función se vería así:
// age.component.ts type ValOrFunc<T> = T | ((...args: unknown[]) => T); @Component({ selector: 'app-age', ... }) class AgeComponent { @Input() age: ValOrFunc<number> constructor() { } getValue<T>(val: ValOrFunc<T>): T { if (val instanceof Function) { return val(); } return val; } } // age.component.html <p> Age is {{ getValue(age) }} </p> Ahora cualquiera que use AgeComponent puede proporcionar la edad como número o función y el valor se actualizará en la plantilla del componente de edad.
El problema es cuando quiero agregar Observable a la ecuación.
// age.component.ts type ValFuncOrObs<T> = T | ((...args: unknown[]) => T) | Observable<T>; @Component({ selector: 'app-age', ... }) class AgeComponent { @Input() age: ValFuncOrObs<number> constructor() { } getValue<T>(val: ValFuncOrObs<T>): T { ??? } } Ahora, ¿cómo debería ser la implementación de getValue ?
También estaba pensando en verificar el tipo en la plantilla y usar AsyncPipe cuando el valor es observable, pero eso parece tedioso y agregaría mucho código repetitivo para el componente con muchas propiedades de entrada.
// age.component.html <p> Age is {{ isObservable(age) ? age | async : getValue(age) }} </p>