# Code Smell 23 - Instance Type Checking

*Do you check who are you talking to?*

> TL;DR: Trust your collaborators. Don't check who they are. Ask them to do instead.

# Problems

- [Coupling](https://maximilianocontieri.com/coupling-the-one-and-only-software-design-problem)

- Metamodel interference

- [IFs](https://maximilianocontieri.com/how-to-get-rid-of-annoying-ifs-forever)

# Solutions

1. Avoid *kind*, *isKindOf*, *instance*, *getClass()*, *typeOf*, etc..

2. Don't use Reflection and [Meta-programming](https://maximilianocontieri.com/laziness-i-meta-programming) for Domain Objects.

3. Replace [*IFs*](https://maximilianocontieri.com/how-to-get-rid-of-annoying-ifs-forever) with polymorphism. 

4. Avoid checking for *'undefined'*. Use [complete objects](https://maximilianocontieri.com/nude-models-part-i-setters), avoid [nulls](https://maximilianocontieri.com/code-smell-12-null) and setters, favor [immutability](https://maximilianocontieri.com/the-evil-powers-of-mutants) and you will never have undefined and ifs.

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/a2307973172b62bb9dc7b11ef7450220)
```javascript
if (typeof(x) === 'undefined') {
    console.log('variable x is not defined');   
}

function isNumber(data) {
  return (typeof data === 'number');
}

function move(animal) {
  if (animal instanceof Rabbit) {
      animal.run()
  }
  if (animal instanceof Seagull) {
      animal.fly()
  } 
}
 
class Rabbit {
  run(){
    console.log("I'm running");
  }  
}

class Seagull {
  fly(){
    console.log("I'm flying");
  }  
}

let bunny = new Rabbit();
let livingstone = new Seagull();

move(bunny);
move(livingstone);
```

## Right

[Gist Url]: # (https://gist.github.com/mcsee/5c0218fcf1362228f406e463f79171a9)
```javascript
/*Avoid these methods
if (typeof(x) === 'undefined') {
    console.log('variable x is not defined');   
}

function isNumber(data) {
  return (typeof data === 'number');
}
*/

class Animal {
} 

class Rabbit extends Animal {
  move(){
    console.log("I'm running");
  }  
}

class Seagull extends Animal {
  move(){
    console.log("I'm flying");
  }  
}

let bunny = new Rabbit();
let livingstone = new Seagull();

bunny.move();
livingstone.move();
```

# Detection

Since type checking methods are well known it is very easy to set up a code policy checking the uses.

# Tags

- Metaprogramming

# Conclusion

Testing for a class type [couples](https://maximilianocontieri.com/coupling-the-one-and-only-software-design-problem) the objects with [accidental decisions](https://maximilianocontieri.com/no-silver-bullet) and violates [bijection](https://maximilianocontieri.com/the-one-and-only-software-design-principle) since no such control exists on real world. It is a smell our models are not good enough.

# Relations

%[https://maximilianocontieri.com/code-smell-12-null]

# More Info

%[https://maximilianocontieri.com/how-to-get-rid-of-annoying-ifs-forever]

%[https://maximilianocontieri.com/laziness-i-meta-programming]

# Credits

Photo by <a href="https://unsplash.com/@gieling">Remy Gieling</a> on <a href="https://unsplash.com/s/photos/assembly-line">Unsplash</a>

* * *

This article is part of the CodeSmell Series.

%[https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code]

*Last update: 2021/07/06*
