'Is it possible to see if the connection parameter is a type of Interface Extension?

I am looking to execute something dependent on the type of connection it is. But have not found a way.

const onSaveHandler = async (connection: Connection) => { 
  if (connection is serial) { // do serial task }

  if (connection is ethernet) { //do ethernet task }
}

All connections have ID, NAME, TYPE,....

export interface Connection {
  [CONNECTION_ID_KEY]: number;
  [CONNECTION_NAME_KEY]: string;
  [CONNECTION_TYPE_ID_KEY]: number;
  [CONNECTION_TYPE_NAME_KEY]?: string;
  [CONNECTION_COMM_INTERVAL_KEY]: number;
}

Two classes extend:

export interface SerialConnection extends Connection {
  [COM_PORT_KEY]: number;
  [BAUD_RATE_KEY]: number;
  [DATA_BITS_KEY]: number;
  [STOP_BITS_KEY]: number;
  [PARITY_KEY]: number;
}

export interface EthernetConnection extends Connection {
  [IP_ADDRESS_KEY]: string;
  [PORT_NUMBER_KEY]: number;
}

To see what I am trying to achieve https://codesandbox.io/s/mbuqb



Solution 1:[1]

You need to make a discriminated union here. That means a union of objects that share a common property. That common property then has a different type for each member of the union.

For example:

export interface CommonConnection {
  common: string
}

export interface SerialConnection extends CommonConnection {
  connectionType: 'serial'
  COM_PORT: number;
  BAUD_RATE: number;
}

export interface EthernetConnection extends CommonConnection {
  connectionType: 'ethernet'
  IP_ADDRESS: string;
  PORT_NUMBER: number;
}

export type Connection = SerialConnection | EthernetConnection

Now you can test the connectionType property at runtime, and typescript will cast your value to the right type for you.

const onSaveHandler = async (connection: Connection) => { 
  if (connection.connectionType === 'serial') {
    console.log(connection.COM_PORT) // can fetch serial property
  }

  if (connection.connectionType === 'ethernet') {
    console.log(connection.IP_ADDRESS) // can fetch ethernet property
  }
}

Playground

Solution 2:[2]

You can also guess the type without adding anything to your hash, by using type-predicates.

    const isSerialConnection = (subject: SerialConnection | EthernetConnection): subject is SerialConnection => {
      return (subject as SerialConnection).COM_PORT_KEY !== undefined;
    };
    
    const isEthernetConnection = (subject: SerialConnection | EthernetConnection): subject is EthernetConnection => {
      return (subject as EthernetConnection).IP_ADDRESS_KEY !== undefined;
    };
    
    const onSaveHandler = async (connection: SerialConnection | EthernetConnection) => { 
      if (isSerialConnection(connection)) { // do serial task }
    
      if (isEthernetConnection(connection)) { //do ethernet task }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alex Wayne
Solution 2 Kruupƶs