instanceof type guards in Typescript - Time & Space Complexity
We want to see how checking types with instanceof affects the time a program takes to run.
How does the time grow when we use instanceof in code that handles many objects?
Analyze the time complexity of the following code snippet.
class Dog { bark() { return "woof"; } }
class Cat { meow() { return "meow"; } }
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
return animal.bark();
} else {
return animal.meow();
}
}
const animals = [new Dog(), new Cat(), new Dog()];
animals.forEach(a => speak(a));
This code checks each animal's type using instanceof and calls the right sound method.
- Primary operation: Looping through the array of animals and checking each with
instanceof. - How many times: Once for each animal in the array.
Each animal requires one instanceof check, so the total checks grow as the number of animals grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 instanceof checks |
| 100 | 100 instanceof checks |
| 1000 | 1000 instanceof checks |
Pattern observation: The number of checks grows directly with the number of animals.
Time Complexity: O(n)
This means the time to run grows in a straight line as the number of objects increases.
[X] Wrong: "Using instanceof is slow and makes the program take forever as the list grows."
[OK] Correct: Each instanceof check is quick and only happens once per item, so the total time grows steadily, not wildly.
Understanding how type checks like instanceof scale helps you write clear and efficient code that works well even with many objects.
"What if we replaced the array with a nested array of animals and checked types inside nested loops? How would the time complexity change?"
Practice
instanceof operator check in TypeScript?Solution
Step 1: Understand the purpose of
Theinstanceofinstanceofoperator checks whether an object was created from a particular class.Step 2: Differentiate from other checks
It does not check primitive types, function returns, or interfaces, only class instances.Final Answer:
If an object is an instance of a specific class -> Option BQuick Check:
instanceofchecks class instance = A [OK]
- Thinking instanceof works with interfaces
- Confusing instanceof with typeof
- Assuming instanceof checks primitive types
obj is an instance of class Car?Solution
Step 1: Recall correct
The correct syntax uses the keywordinstanceofsyntaxinstanceofbetween the object and the class name.Step 2: Identify invalid options
Options B, C, and D use incorrect keywords or missing syntax.Final Answer:
if (obj instanceof Car) { } -> Option AQuick Check:
Correct syntax uses instanceof keyword = A [OK]
- Using 'is' or 'type' instead of 'instanceof'
- Omitting parentheses around condition
- Writing 'instance' instead of 'instanceof'
class Dog { bark() { return 'woof'; } }
class Cat { meow() { return 'meow'; } }
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
return animal.bark();
} else {
return animal.meow();
}
}
console.log(speak(new Cat()));Solution
Step 1: Identify the object passed
The functionspeakis called withnew Cat(), soanimalis a Cat instance.Step 2: Check the instanceof condition
The conditionanimal instanceof Dogis false, so the else block runs, returninganimal.meow().Final Answer:
'meow' -> Option CQuick Check:
Cat instance triggers else block = D [OK]
- Assuming instanceof works with interfaces
- Confusing which method runs for which class
- Expecting 'woof' when passing Cat instance
interface Bird { fly(): void; }
class Eagle implements Bird { fly() { console.log('Flying'); } }
function check(bird: Bird) {
if (bird instanceof Eagle) {
bird.fly();
}
}Solution
Step 1: Understand instanceof usage
Theinstanceofoperator is used with the classEagle, which is valid even thoughbirdis typed as the interfaceBird.Step 2: Verify no errors
There are no syntax errors, type mismatches, or runtime issues. TypeScript compiles this code and narrowsbirdtoEagleinside theifblock.Final Answer:
No error, code is correct -> Option AQuick Check:
instanceof with class on interface-typed param works = D [OK]
- Thinking instanceof can't be used on interface-typed variables
- Confusing instanceof with direct interface checks
- Thinking implementing class must be abstract
class Animal { name: string; constructor(name: string) { this.name = name; } }
class Fish extends Animal { swim() { return 'swimming'; } }
class Bird extends Animal { fly() { return 'flying'; } }Write a function
move that takes animal: Animal and returns 'swimming' if it's a Fish, 'flying' if it's a Bird, or 'unknown' otherwise. Which implementation is correct?Solution
Step 1: Check instanceof order and method calls
The function must check ifanimalis aFishorBirdusinginstanceofand call the correct method.Step 2: Validate each option
function move(animal: Animal) { if (animal instanceof Fish) return animal.swim(); else if (animal instanceof Bird) return animal.fly(); else return 'unknown'; } correctly checksFishfirst, callsswim(), thenBirdwithfly(), else returns 'unknown'. function move(animal: Animal) { if (animal instanceof Animal) return 'unknown'; else if (animal instanceof Fish) return animal.swim(); else return animal.fly(); } wrongly checksAnimalfirst, which always matches. function move(animal: Animal) { if (animal instanceof Fish) return animal.fly(); else if (animal instanceof Bird) return animal.swim(); else return 'unknown'; } swaps methods incorrectly. function move(animal: Animal) { if (animal instanceof Fish) return 'flying'; else if (animal instanceof Bird) return 'swimming'; else return 'unknown'; } returns incorrect strings directly without calling methods.Final Answer:
function move(animal: Animal) { if (animal instanceof Fish) return animal.swim(); else if (animal instanceof Bird) return animal.fly(); else return 'unknown'; } -> Option DQuick Check:
Correct instanceof checks and method calls = B [OK]
- Checking base class first, blocking subclass checks
- Calling wrong methods for classes
- Returning strings instead of calling methods
Ready to prove it?
Pass the test and this pattern moves unknown
