Note: I'm new to typescript. Prior to posting I read the docs regarding advance types and type guards. In addition I also read several related S.O. question (e.g. user defined type guards [typescript], and How to write a user defined type guard for "string" | "literal" | "types"?)
Most similar to my question is the later question where you might have some custom type on a literal (in this instance string
, but the solution should apply to number
as well) e.g.
type Format = 'JSON' | 'CSV' | 'XML'
In the second question the user asks in regards to a solution of typescript's keyof
key word and @Ryan Cavanaugh's answer goes about this via changing the type from a literal
to an interface
and checking the keys of the interface:
// copy-pasted from answer for convenience
interface McuParams {
foo, bar, baz;
}
function isKeyOfMcuParams(x: string): x is keyof McuParams {
switch (x) {
case 'foo':
case 'bar':
case 'baz':
return true;
default:
return false;
}
}
My question is specifically if there is a way to do user defined type guards using the type itself e.g.
const isFormat = (maybe:String|Format): maybe is Format => /* something goes here */
To my knowledge the following does not work (replacing just /* something goes here */
):
// 1
/*
* As stated in the docs "The right side of the instanceof needs to
* be a constructor function" but we have a literal
*/
maybe instaceof Format
//2
/* As stated in the docs "typename" must be "number",
* "string", "boolean", or "symbol"
*/
typeof maybe === 'format'
//3
/* no idea */
(<Format>maybe)
So is @Ryan Cavanaugh's answer the only viable solution? It seems extremely verbose...