📖 Scenario: Imagine you are building a simple app that tracks different types of pets and their unique details. You want to make sure your program handles each pet type correctly and safely.
🎯 Goal: You will create a basic data structure for pets, add a type to distinguish pet kinds, write code that uses advanced types to handle different pet details safely, and finally display the pet information.
📋 What You'll Learn
Create a list of pets with exact properties
Add a type property to each pet to identify its kind
Use a TypeScript union type to define pet types
Use a type guard with switch to handle each pet kind
Print the pet details with correct type safety
💡 Why This Matters
🌍 Real World
In real apps, you often have data that can be different types but share some common parts. Advanced types help you write code that works correctly for each kind.
💼 Career
Understanding advanced types is important for writing safe, maintainable TypeScript code in professional software development.
Progress0 / 4 steps
1
Create the initial pet list
Create a variable called pets as an array with these exact objects: { name: 'Buddy', age: 3, type: 'dog' }, { name: 'Mittens', age: 2, type: 'cat' }, and { name: 'Goldie', age: 1, type: 'fish' }.
Typescript
Hint
Use const pets = [ ... ] with the exact objects inside.
2
Define the Pet type using union types
Create a TypeScript type called Pet as a union of three object types: { name: string; age: number; type: 'dog'; barkVolume: number; }, { name: string; age: number; type: 'cat'; livesLeft: number; }, and { name: string; age: number; type: 'fish'; waterType: string; }.
Typescript
Hint
Use the type keyword and union | to combine the three pet object types.
3
Add pet details using the Pet type
Create a new variable called detailedPets as an array of Pet objects. Add the same pets as before but include these extra properties: for the dog add barkVolume: 5, for the cat add livesLeft: 9, and for the fish add waterType: 'freshwater'.
Typescript
Hint
Use const detailedPets: Pet[] = [ ... ] with the exact objects including the extra properties.
4
Print pet details using a type guard
Use a for loop with variable pet to go through detailedPets. Inside the loop, use a switch on pet.type to print these exact lines: for 'dog' print "Dog: Buddy barks at volume 5", for 'cat' print "Cat: Mittens has 9 lives left", and for 'fish' print "Fish: Goldie lives in freshwater water".
Typescript
Hint
Use a for loop and a switch on pet.type. Print the exact lines with console.log.
Practice
(1/5)
1. Why do we need advanced types in TypeScript?
easy
A. To avoid writing any type annotations
B. To make the code run faster at runtime
C. To describe complex data shapes clearly and catch errors early
D. To allow JavaScript code to run without changes
Solution
Step 1: Understand the purpose of advanced types
Advanced types help describe complex data structures and relationships in code.
Step 2: Recognize their benefit in error checking
They allow TypeScript to catch mistakes before running the code by checking data shapes.
Final Answer:
To describe complex data shapes clearly and catch errors early -> Option C
Quick Check:
Advanced types = clear data + early error catch [OK]
Hint: Advanced types describe complex data and catch errors early [OK]
Common Mistakes:
Thinking advanced types speed up runtime
Believing they remove the need for any types
Confusing advanced types with JavaScript features
2. Which of the following is a correct way to define a union type in TypeScript?
easy
A. let value: string | number;
B. let value: string & number;
C. let value: string or number;
D. let value: string, number;
Solution
Step 1: Recall union type syntax
Union types use the pipe symbol | to allow multiple types.
Step 2: Check each option
let value: string | number; uses | correctly; B uses & which means intersection, not union; C and D use invalid syntax.
Final Answer:
let value: string | number; -> Option A
Quick Check:
Union type uses | symbol [OK]
Hint: Union types use | between types, not & or words [OK]
Common Mistakes:
Using & instead of | for union types
Writing 'or' instead of |
Separating types with commas
3. What will be the output of this TypeScript code?
type Result = string | number; function format(value: Result) { if (typeof value === 'string') { return value.toUpperCase(); } else { return value.toFixed(2); } } console.log(format(3.14159));
medium
A. "3.14"
B. "3.14" (number) with two decimals
C. "3.14159"
D. "3.14" (string) with two decimals
Solution
Step 1: Understand the function behavior
If the input is a string, it converts to uppercase. Otherwise, it formats the number to 2 decimals using toFixed(2).
Step 2: Apply the function to 3.14159
3.14159 is a number, so toFixed(2) returns the string "3.14" with two decimals.
Final Answer:
"3.14" (string) with two decimals -> Option D
Quick Check:
Number input uses toFixed(2) = "3.14" [OK]
Hint: Check type guards to predict output format [OK]
Common Mistakes:
Thinking toFixed returns a number, not string
Confusing string input with number input
Ignoring type narrowing in if statement
4. Identify the error in this TypeScript code using advanced types:
type User = { name: string; age: number } | null; function greet(user: User) { console.log("Hello, " + user.name.toUpperCase()); }
medium
A. user can be null, so accessing user.name causes an error
B. toUpperCase() is not a function on string
C. Missing return type in function greet
D. User type should not use union with null
Solution
Step 1: Analyze the User type
User can be an object or null, so user might be null at runtime.
Step 2: Check the function usage
Accessing user.name without checking if user is null causes a runtime error.
Final Answer:
user can be null, so accessing user.name causes an error -> Option A
Quick Check:
Null union requires null check before property access [OK]
Hint: Always check for null before accessing properties [OK]
Common Mistakes:
Ignoring null possibility in union types
Assuming string methods work on null
Thinking missing return type causes error here
5. You have a function that accepts a parameter which can be either a string or an array of strings. You want to return a single string that joins all strings with commas. Which advanced type and code snippet correctly handles this?
hard
A. function joinStrings(input: string[]) { return input.toString(); }
B. function joinStrings(input: string | string[]) { return Array.isArray(input) ? input.join(",") : input; }
C. function joinStrings(input: string | string[]) { return input.join(","); }
D. function joinStrings(input: string & string[]) { return input.join(","); }
Solution
Step 1: Understand the parameter type
The parameter can be a string or an array of strings, so union type string | string[] is correct.
Step 2: Handle both cases safely
Use Array.isArray to check if input is array, then join with commas; else return the string as is.
Final Answer:
function joinStrings(input: string | string[]) { return Array.isArray(input) ? input.join(",") : input; } -> Option B
Quick Check:
Use union type + type guard for safe handling [OK]
Hint: Use union type and Array.isArray to handle both cases [OK]
Common Mistakes:
Using intersection type & instead of union |
Calling join on string without checking type
Ignoring the string input case
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.