interface SubscriptionParams { selectedProduct?: SubscriptionSelectedProduct; } interface SubscriptionSelectedProduct { productId?: string; pricingId?: string; childProduct?: SubscriptionSelectedProduct; } function getChildIdRecursively(product: SubscriptionSelectedProduct, ids: string[]) { if (product) { ids.push(product.productId!); product.childProduct && getChildIdRecursively(product.childProduct, ids); } } function subscriptionProductsIds(subscription: SubscriptionParams): string[] { let ids: string[] = [subscription.selectedProduct?.productId!]; if (subscription.selectedProduct?.childProduct) { getChildIdRecursively(subscription.selectedProduct?.childProduct, ids); } return ids; }Cómo hacer esta recursión sin mutación, ahora estoy mutando la matriz de ids. Quiero seguir los principios de programación funcional.
Creo que podrías resolver esto aprovechando los cruces de árboles en mi humilde opinión.
const collectIds = (node) => { const { id, children = [] } = node; // const children = [product.childProduct] in your specific case const ids = children.flatMap(collectIds); return [id, ...ids]; }; const product = { id: 'L1', children: [ { id: 'L1.1' }, { id: 'L1.2', children: [ { id: 'L1.2.1', }, { id: 'L1.2.2', }, { id: 'L1.2.3', }, { id: 'L1.2.4', }, { id: 'L1.2.5', }, ], }, ], }; console.log( collectIds(product), );Evitaría crear muchas matrices intermedias innecesarias, pero cada una por su cuenta. Hacer que esto sea "inmutable" es tan fácil como devolver una nueva matriz desde getChildIdRecursively . Además, dado que básicamente está duplicando la lógica en subscriptionProductsIds , puede eliminar eso.
function getChildIdRecursively(product: SubscriptionSelectedProduct) { if (product) { let ids: string[] = [product.productId!]; if (product.childProduct) { ids = ids.concat(getChildIdRecursively(product.childProduct)); } return ids; } return []; } function subscriptionProductsIds(subscription: SubscriptionParams): string[] { return getChildIdRecursively(subscription.selectedProduct) }