Roddy
Roddy

Reputation: 68114

Typescript runtime type testing

I have a Typescript class method (using the DefinitelyTyped JQuery definitions) that I want to look like this:

  DoStuff(data: JQuery | string) {
    if (data instanceof JQuery) 
      DoThis()
    else
      DoThat(); 
  }

But the instanceof line gives the error: 'JQuery' only refers to a type, but is being used as a value here.

What's the right way of doing this? I could obviously use typeof(data) != "string" but that feels like cheating.

Upvotes: 2

Views: 208

Answers (2)

Saravana
Saravana

Reputation: 40712

You can define an user-defined guard to check if the parameter is a jQuery instance:

import * as $ from "jquery";

function isJquery(arg: any): arg is JQuery {
  return arg instanceof $; // Notice that this checks against the real jQuery object and not the interface `JQuery`
}

function DoStuff(data: JQuery | string) {
  if (isJquery(data))
    // `data` will be typed as `JQuery` here
    DoThis();
  else
    // `data` will be typed as `string` here
    DoThat();
}

Upvotes: 1

Fenton
Fenton

Reputation: 251292

You will need a custom type guard to determine whether you have jQuery or not.

The example below is too lightweight for production, as other objects may have an append function - you would want to check enough of the duck to make sure it is a duck, not just the beak. It does demonstrate how to use a custom type guard though:

function isJquery(obj: JQuery | any): obj is JQuery {
    return typeof (<JQuery>obj).append === 'function';
}

var x: JQuery | string;

if (isJquery(x)) {
    x.append('Something');
} else {
    x.indexOf('blah...');
}

Upvotes: 2

Related Questions