CodexBloom - Programming Q&A Platform

TypeScript: Type Narrowing optimization guide as Expected with Union Types and Generics

👀 Views: 463 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-06
typescript generics type-narrowing TypeScript

I'm working with an scenario with TypeScript where type narrowing doesn't seem to work as expected when I'm using union types along with generics. I have a function that takes an array of items which can be either `string` or an object with a `name` property. The goal is to process the array and handle each type accordingly, but the compiler throws an behavior when I try to access properties on the second type. Here's a simplified version of my code: ```typescript type Item = string | { name: string }; function processItems<T extends Item>(items: T[]): void { items.forEach(item => { if (typeof item === 'string') { console.log(`String item: ${item}`); } else { // TypeScript behavior here: Property 'name' does not exist on type 'Item'. console.log(`Object item: ${item.name}`); } }); } const items: Item[] = ['apple', { name: 'banana' }, 'cherry', { name: 'date' }]; processItems(items); ``` When I try to compile this code, TypeScript gives me an behavior: `Property 'name' does not exist on type 'Item'`. I've tried using type assertions and adding a type guard function, but nothing seems to resolve the scenario. Here's what I tried: 1. Changing the signature to `function processItems(items: Item[]): void`, but that resulted in the same behavior. 2. Using a type guard function: ```typescript function isObjectWithName(item: Item): item is { name: string } { return typeof item === 'object' && item !== null && 'name' in item; } ``` Then using it like this: ```typescript if (isObjectWithName(item)) { console.log(`Object item: ${item.name}`); } ``` This approach works, but it feels overly complicated and not as clean as I expected. Is there a more straightforward way to handle this situation in TypeScript? Am I missing something in my initial setup that would allow type narrowing to function as intended? Any help or insights would be greatly appreciated! For context: I'm using Typescript on Windows. Thanks in advance!