Skip to content
Advertisement

Generic type guard including primitives

I’m trying to create a generic type guard, I’ve read answers that led me to this solution:

JavaScript

This works for any class that has a constructor, e.g.:

JavaScript

I’m having trouble getting this to work for something like:

JavaScript

or

JavaScript

I’ve tried this:

JavaScript

But this implementation doesn’t let me look into what T is and do something like if typeof o === T or something like that.

Is there a way to implement this? Theoretically I’d like to pass string as the constructor argument like typeGuard(5, string) but this would require constructors type to be: { new(...args: any[]): T } | Type<string> | Type<number> | Type<boolean> but I don’t know how to implement this in typescript.

Example of use:

JavaScript

Advertisement

Answer

I’m still not sure what the real need is for this to be a single function, but let’s see what we can do. You need to provide, at runtime, a value for the function to use to determine if you’re checking for a string, number, or something else.

Let’s say that the second argument to typeGuard() is called sentinel, of type Sentinel, which can either be a constructor, or one of the string values corresponding to what typeof gives you.

JavaScript

Then, given a value of a type that extends Sentinel, the type you’re guarding is related to the type of Sentinel via the following conditional type:

JavaScript

And you can implement typeGuard() like this:

JavaScript

(† See Microsoft/TypeScript#13995 for the reason for concreteSentinel)

And here’s how you’d use it:

JavaScript

Does that make sense?

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement