10 TypeScript Best Practices Developers Often Miss (With Examples) Quiz

Discover essential TypeScript coding best practices that help prevent subtle bugs and make your codebase robust, maintainable, and readable. Learn strategies that go beyond the basics for writing cleaner TypeScript in everyday frontend development.

  1. Unknown vs Any

    Why is it generally considered better practice to use the 'unknown' type instead of 'any' in TypeScript functions that handle external input?

    1. Because 'unknown' requires type checks before use, preventing unsafe operations
    2. Because 'unknown' automatically narrows to the correct type
    3. Because 'any' increases runtime performance
    4. Because 'unknown' values can be used as any type automatically

    Explanation: Using 'unknown' forces explicit type-checking before using the value, making the code safer and less prone to runtime errors. 'unknown' does not automatically narrow types; type checks must be performed. 'any' sacrifices type safety for flexibility, not performance. 'unknown' values cannot be used as any type automatically; attempts to do so cause compiler errors until type-checked.

  2. Enums vs Union Types

    When is it more appropriate to use a union of string literals instead of an enum in TypeScript?

    1. When you want to extend the set at runtime
    2. When you need to attach methods to each value
    3. When you require numeric indexing
    4. When you only need a set of possible string values and do not require extra runtime properties

    Explanation: A union of string literals is well-suited for cases requiring just a set of named string values, with no methods or runtime behaviors attached. Attaching methods is not available for union types. Numeric indexing and runtime extension are features more relevant to enums or classes, not basic union types.

  3. Optional vs Undefined

    How should you indicate that a function parameter is optional in TypeScript for the best type clarity?

    1. By using 'any' as the parameter type
    2. By using a question mark (e.g., param?: string)
    3. By assigning the type 'undefined' (e.g., param: string | undefined)
    4. By omitting the parameter from the function definition entirely

    Explanation: A question mark is the standard way to indicate that a parameter is optional in TypeScript, making the intent clear and readable. Using 'string | undefined' is possible but less concise and may not convey intent as clearly. Omitting the parameter would make it required. Using 'any' sacrifices type safety and clarity.

  4. Type Assertions vs Type Guards

    If you receive an unknown value and need to access a specific property safely, what is the best practice to ensure type safety in TypeScript?

    1. Use 'any' to cast the value so you can access any property
    2. Use a type guard to check the structure before accessing properties
    3. Trust that the value conforms and access properties directly
    4. Directly assert the type with 'as', bypassing checks

    Explanation: Type guards let you check the shape or type at runtime, ensuring safety before property access. Direct type assertions bypass safety checks, risking runtime errors. Assuming the value structure without checks can result in crashes. Casting to 'any' hides issues and disables compile-time safety.

  5. Avoid Useless Type Annotations

    Why is it advisable to avoid explicit type annotations when TypeScript can infer the type from initialization?

    1. Because TypeScript cannot handle inference for any variable
    2. Because redundant type annotations increase code verbosity without adding safety
    3. Because omitting types makes functions inaccessible
    4. Because type annotations reduce performance of compiled JavaScript

    Explanation: When TypeScript can infer the type, explicit annotations do not improve safety and just add unnecessary noise. TypeScript's inference works well in many cases. Annotations have no impact on JavaScript runtime performance. Omitting a type does not make functions inaccessible.