Bird
Raised Fist0
Typescriptprogramming~20 mins

Custom type guard functions in Typescript - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Custom Type Guard Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a custom type guard function
What is the output of the following TypeScript code when run with console.log(isStringOrNumber(42));?
Typescript
function isStringOrNumber(value: unknown): value is string | number {
  return typeof value === 'string' || typeof value === 'number';
}

console.log(isStringOrNumber(42));
Afalse
Bundefined
CTypeError
Dtrue
Attempts:
2 left
💡 Hint
Think about what the function checks for the input value.
🧠 Conceptual
intermediate
1:30remaining
Purpose of custom type guard functions
What is the main purpose of a custom type guard function in TypeScript?
ATo declare a new type alias
BTo convert a variable from one type to another
CTo check the type of a variable at runtime and inform the compiler about it
DTo throw an error if a type is incorrect
Attempts:
2 left
💡 Hint
Think about how TypeScript uses these functions to help with type safety.
🔧 Debug
advanced
2:00remaining
Identify the error in this custom type guard
What error will this TypeScript code produce when compiled?
function isArrayOfStrings(value: any): value is string[] {
  return Array.isArray(value) && value.every(item => typeof item === 'string');
}

const test = isArrayOfStrings(['hello', 5]);
Typescript
function isArrayOfStrings(value: any): value is string[] {
  return Array.isArray(value) && value.every(item => typeof item === 'string');
}

const test = isArrayOfStrings(['hello', 5]);
ANo error, test is false
BTypeError at runtime
Ctest is true
DSyntaxError
Attempts:
2 left
💡 Hint
Check what the function returns for the given input.
📝 Syntax
advanced
1:30remaining
Correct syntax for a custom type guard
Which option shows the correct syntax for a custom type guard function that checks if a value is a boolean?
A
function isBoolean(value: any): boolean {
  return typeof value === 'boolean';
}
B
function isBoolean(value: any): value is boolean {
  return typeof value === 'boolean';
}
C
function isBoolean(value: any): value is bool {
  return typeof value === 'boolean';
}
D
function isBoolean(value: any): value is Boolean {
  return typeof value === 'boolean';
}
Attempts:
2 left
💡 Hint
Remember the exact syntax for type predicates in TypeScript.
🚀 Application
expert
2:30remaining
Using a custom type guard in conditional code
Given the custom type guard below, what will be the output of the code?
interface Cat { meow: () => void; }
interface Dog { bark: () => void; }

type Pet = Cat | Dog;

function isCat(pet: Pet): pet is Cat {
  return (pet as Cat).meow !== undefined;
}

const pet: Pet = { bark: () => console.log('Woof!') };

if (isCat(pet)) {
  pet.meow();
} else {
  pet.bark();
}
Typescript
interface Cat { meow: () => void; }
interface Dog { bark: () => void; }

type Pet = Cat | Dog;

function isCat(pet: Pet): pet is Cat {
  return (pet as Cat).meow !== undefined;
}

const pet: Pet = { bark: () => console.log('Woof!') };

if (isCat(pet)) {
  pet.meow();
} else {
  pet.bark();
}
AWoof!
BError: pet.meow is not a function
CNo output
DWoof! Woof!
Attempts:
2 left
💡 Hint
Check what the type guard returns and which branch runs.

Practice

(1/5)
1. What is the main purpose of a custom type guard function in TypeScript?
easy
A. To declare a new type alias
B. To convert a value from one type to another
C. To check if a value matches a specific type and help TypeScript narrow types
D. To throw an error when a type mismatch occurs

Solution

  1. Step 1: Understand what a type guard does

    A type guard checks if a value is of a certain type at runtime.
  2. Step 2: Recognize the benefit in TypeScript

    It helps TypeScript narrow the type, making code safer and clearer.
  3. Final Answer:

    To check if a value matches a specific type and help TypeScript narrow types -> Option C
  4. Quick Check:

    Type guard = check type + narrow [OK]
Hint: Type guards confirm type and help TypeScript narrow it [OK]
Common Mistakes:
  • Thinking type guards convert types
  • Confusing type guards with error handling
  • Believing type guards declare new types
2. Which of the following is the correct syntax for a custom type guard function named isString that checks if a value is a string?
easy
A. function isString(value: any): value is string { return typeof value === 'string'; }
B. function isString(value: any): boolean { return typeof value === 'string'; }
C. function isString(value: any): string { return typeof value === 'string'; }
D. function isString(value: any): value is boolean { return typeof value === 'string'; }

Solution

  1. Step 1: Identify the return type for a type guard

    A custom type guard returns a type predicate like value is string.
  2. Step 2: Check the function body

    The function should return true if typeof value === 'string'.
  3. Final Answer:

    function isString(value: any): value is string { return typeof value === 'string'; } -> Option A
  4. Quick Check:

    Type guard syntax = value is Type [OK]
Hint: Type guard return type uses 'value is Type' syntax [OK]
Common Mistakes:
  • Using boolean instead of type predicate as return type
  • Returning wrong type predicate
  • Returning the type instead of a boolean
3. What will be the output of the following TypeScript code?
function isNumber(value: any): value is number {
  return typeof value === 'number';
}

const input: any = 42;
if (isNumber(input)) {
  console.log(input.toFixed(2));
} else {
  console.log('Not a number');
}
medium
A. 42.00
B. Not a number
C. Error: toFixed is not a function
D. undefined

Solution

  1. Step 1: Check the type guard function behavior

    The function isNumber returns true if value is a number.
  2. Step 2: Analyze the if condition and output

    Since input is 42 (a number), the if block runs and input.toFixed(2) outputs '42.00'.
  3. Final Answer:

    42.00 -> Option A
  4. Quick Check:

    isNumber(42) = true, so prints 42.00 [OK]
Hint: If type guard true, use narrowed type safely [OK]
Common Mistakes:
  • Assuming input is not a number
  • Expecting runtime error on toFixed
  • Confusing output with string conversion
4. Identify the error in this custom type guard function and choose the fix:
function isArray(value: any): value is Array {
  return Array.isArray(value);
}
medium
A. Change function name to 'isArrayType'
B. Change return type to 'value is any[]' instead of 'value is Array'
C. Add explicit type annotation to parameter 'value: unknown'
D. Replace 'Array.isArray' with 'typeof value === "array"'

Solution

  1. Step 1: Understand the return type syntax

    The return type should be a type predicate with a specific type, e.g., value is any[] for arrays.
  2. Step 2: Identify the incorrect type usage

    Array alone is a constructor, not a type for arrays. Use any[] or a typed array instead.
  3. Final Answer:

    Change return type to 'value is any[]' instead of 'value is Array' -> Option B
  4. Quick Check:

    Array type predicate = value is any[] [OK]
Hint: Use 'value is Type[]' for arrays in type guards [OK]
Common Mistakes:
  • Using 'Array' instead of 'any[]' or typed array
  • Changing function name unnecessarily
  • Using typeof 'array' which is invalid
5. Given the following types and function, which implementation correctly narrows the type to Dog using a custom type guard?
interface Dog { bark(): void; }
interface Cat { meow(): void; }

type Pet = Dog | Cat;

function isDog(pet: Pet): pet is Dog {
  // Which implementation is correct?
}
hard
A. return pet.meow === undefined;
B. return pet instanceof Dog;
C. return typeof pet.bark === 'function';
D. return (pet as Dog).bark !== undefined;

Solution

  1. Step 1: Understand the interfaces and type guard goal

    We want to check if pet has a bark method to confirm it's a Dog.
  2. Step 2: Evaluate the implementations

    Directly accessing pet.bark or pet.meow causes TypeScript compile errors because those properties do not exist on the union type Pet.
    pet instanceof Dog does not work because Dog is an interface, not a class with a constructor.
    Using (pet as Dog).bark !== undefined compiles due to the type assertion and performs a runtime check to see if the bark property exists.
  3. Final Answer:

    return (pet as Dog).bark !== undefined; -> Option D
  4. Quick Check:

    Type assertion enables property check in union type guards [OK]
Hint: Use type assertion inside type guards for union property checks [OK]
Common Mistakes:
  • Using instanceof with interfaces
  • Directly accessing properties on union types
  • Checking absence of other type's method
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard