29

Given the following code:

module MyModule {
  export interface IMyInterface {}
  export interface IMyInterfaceA extends IMyInterface {}
  export interface IMyInterfaceB extends IMyInterface {}

  function(my: IMyInterface): void {
    if (my instanceof IMyInterfaceA) {
      // do something cool
    }
  }
}

I get the error "Can't find name IMyInterfaceA". What's the correct way to handle this situation?

Bart van den Burg
  • 2,166
  • 4
  • 25
  • 42
  • Possible duplicate of [Interface type check with Typescript](https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) – Krisztián Balla Nov 24 '17 at 08:05

2 Answers2

23

There is no way to runtime check an interface as type information is not translated in any way to the compiled JavaScript code.

You can check for a specific property or a method and decide what to do.

module MyModule {
  export interface IMyInterface {
      name: string;
      age: number;
  }
  export interface IMyInterfaceA extends IMyInterface {
      isWindowsUser: boolean;
  }
  export interface IMyInterfaceB extends IMyInterface {

  }

  export function doSomething(myValue: IMyInterface){
    // check for property
    if (myValue.hasOwnProperty('isWindowsUser')) {
      // do something cool
    }
  }
}
Matija Grcic
  • 12,963
  • 6
  • 62
  • 90
  • 5
    Instead of `hasOwnProperty`,it be more idiomatic to use [`in` operator narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-in-operator-narrowing). Then the control flow analysis / type inference works -- if you do `if ('isWindowsUser' in myValue) { ... }`, then inside the condition, TS correctly narrows the type -- it infers that `myValue` implements `IMyInterfaceA`. – Dan Drake Oct 26 '21 at 13:21
8

TypeScript uses duck typing for interfaces, so you should just check if object contains some specific members:

if ((<IMyInterfaceA>my).someCoolMethodFromA) {
    (<IMyInterfaceA>my).someCoolMethodFromA();
}
Artem
  • 1,773
  • 12
  • 30
  • 3
    Note if you're in a `.tsx` file, the `<>` syntax won't work. Alternative is to cast using `as`: `(my as IMyInterfaceA).someCoolMethodFromA` – Jans Rautenbach Nov 04 '21 at 06:36