Skip to main content
In this lesson we combine several TypeScript fundamentals—enums, union types, interfaces, classes with implements, optional parameters, and array usage—into a small “duck pond” management example. Along the way we highlight code-quality ideas such as preferring pure functions and using explicit typing when it improves clarity. Below is the cleaned and complete TypeScript implementation used for this lesson. It demonstrates the concepts above and includes both pure and impure function examples.
Discussion and key points
  • Explicit typing vs inference
    • Declaring const duckPond: PondDuck[] = [] makes it explicit that only PondDuck instances can be added to that array. This is useful when the container starts empty or receives external data.
    • If you instead define an array from existing elements (for example, const duckPondInferred = [daffy, donald, howard];), TypeScript will infer the element type from those items. Attempts to push a different type (e.g. a string) will produce a compile-time error.
    • Prefer inference when it reduces boilerplate, but favor explicit types at boundaries (empty containers, external inputs).
  • Pure functions vs impure functions
    • makeAllDucksQuack(ducks, times) follows a pure-style approach because it receives all required inputs as parameters.
    • findDuckAndFly_impure(name) reads duckPond from the outer scope; it depends on external state and is therefore impure. The pure variant findDuckAndFly(name, pond) is easier to test and reuse.
  • Interfaces and implements
    • The implements IDuck on PondDuck enforces that the class matches the interface shape (at least the specified properties), helping catch structure mismatches at compile time.
  • Optional parameters and defaults
    • Both quack(times = 1) and makeAllDucksQuack(ducks, times = 1) demonstrate default parameter values.
    • Optional properties on types and interfaces use the ? suffix (for example, favoriteToy?: string).
  • Small utility functions
    • Utilities like countDucksByType help keep logic isolated, readable, and simple to test.
Function summary
Prefer pure functions when possible — functions that accept all inputs and avoid accessing or mutating external state are easier to reason about, test, and reuse.
A presentation slide titled "Syntax – Key Takeaways" that summarizes TypeScript/JavaScript concepts like variables, primitive and complex types, variable declarations (let/const), arrays/objects, type inference, classes, and enums/union types. It lists brief definitions and examples for each bullet point.
Summary
  • We modeled structured data using enums and union types, and enforced shape with interfaces.
  • We implemented a class (PondDuck) with methods and optional properties, then managed instances in an explicitly typed array.
  • We contrasted pure and impure designs and showed simple utility functions for common pond operations.
  • Use TypeScript inference to reduce boilerplate, but declare explicit types at public or empty boundaries for safety.
  • Favor small, pure utilities for clarity, reusability, and easier testing.
A presentation slide titled "Syntax – Advanced TypeScript Concepts" that lists next-step topics (Generics, Utility Types, Core JavaScript, Async/Await, Decorators) with short descriptions. The slide appears to be from KodeKloud and recommends these topics to deepen TypeScript skills.
Next steps (recommended)
  • Generics and reusable data structures
  • Utility types (Partial, Pick, Record, etc.)
  • Deeper core JavaScript concepts (closures, prototype, event loop)
  • Async/await patterns and Promise handling
  • Decorators and advanced class patterns
Links and references

Watch Video

Practice Lab