Typescript narrowing of keys in objects when passed to function

This is ultimately a design limitation of TypeScript. It does not use type guards on an object’s properties to narrow the object itself, except in the particular case where the object is a discriminated union type… and in your case, A isn’t a union at all, let alone a discriminated one.

The way I’d do this for your case is to introduce a user-defined type guard function which explicitly performs the narrowing you expect: you pass in an object with a key property, and return true or false depending on whether or not this object is a valid B:

const isB = (x: { key: any }): x is B => typeof x.key === "string";

Then you use it:

if (isB(a)) {
  func(a); // okay
}

This is (give or take a function call) essentially the same logic as your code, but the compiler recognizes your intent now. Okay, hope that helps; good luck!

Link to code

Leave a Comment