CodexBloom - Programming Q&A Platform

TypeScript: Type 'never' when using type guards with a union of objects

👀 Views: 81 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-09
typescript type-guard union-types TypeScript

I'm working on a personal project and I'm maintaining legacy code that After trying multiple solutions online, I still can't figure this out... I'm working with a frustrating scenario with TypeScript when trying to implement type guards on a union of object types. I have two interfaces, `Cat` and `Dog`, both containing a `name` property, but only `Dog` has a `bark` method. Here's the relevant code: ```typescript interface Cat { name: string; } interface Dog { name: string; bark: () => void; } type Pet = Cat | Dog; function petSound(pet: Pet) { if ('bark' in pet) { pet.bark(); // This works fine. } else { console.log(`${pet.name} says hello.`); // This also works. } } ``` The above code compiles without errors, but when I call `petSound({ name: 'Fluffy' })`, I'm getting a TypeScript behavior: ``` Argument of type '{ name: string; }' is not assignable to parameter of type 'Pet'. Type '{ name: string; }' is not assignable to type 'never'. ``` I've double-checked that the `Pet` type is correctly defined as a union of `Cat` and `Dog`, and I don't understand why TypeScript thinks that an object with just the `name` property is causing a conflict. I also tried using the `unknown` type as a workaround, but it didn't resolve the scenario. This only happens when I attempt to call `petSound` with an object literal. If I first assign the object to a variable of type `Cat`, it works as expected: ```typescript const myCat: Cat = { name: 'Whiskers' }; petSound(myCat); // This works fine ``` So, what could be causing TypeScript to infer the type as `never` in the first case? How can I fix this and make sure that TypeScript also understands that the literal object passed as an argument satisfies the `Pet` type? Am I missing something obvious? This is my first time working with Typescript 3.9. Any feedback is welcome! I'm on Debian using the latest version of Typescript. This is happening in both development and production on Windows 10. Any ideas how to fix this?