A lot of people don’t seem to be aware that there are a bunch of excellent runtime validation libraries that one can use to encode runtime validation checks which produce the typescript types for you (so you rarely have to write ”T is Cat” yourself where it is easy to introduce a false type) but instead can write (or even generate) trustworthy decoders that give you the types. There’s too many of these very-similar libraries to list but some of the more popular ones include io-ts, zod, purify-ts,and suretype.
And while there’s no instanceof that works for non-class structured data like this, (and it wouldn’t be particularly necessary in TS only codebases), even if you were in a mixed repo where there’s a bunch of untyped JS, you could fairly easily create a wrapper with the same behavior of instanceof even without resorting to classes by using symbols. So long as the data is nonmutable, you can effectively get the equivalent of an O(1) instanceof check in JS code, but with a bit more ceremony.