interface vs type
Question Variations
- "What is the difference between `interface` and `type` in TypeScript?"
- "When would you prefer using a `type` over an `interface`?"
- "Explain the concept of 'declaration merging' and which keyword supports it."
- "How do you extend an `interface` compared to extending a `type` alias?"
Why This Is Asked
This is a quick litmus test for TypeScript experience. Interviewers want to see if you know the practical differences — especially declaration merging — and have a reasoned opinion on when to use each, rather than just a default preference.
Key Concepts
interfacesupports declaration merging (defining the same interface twice merges them),typedoes nottypecan represent unions, intersections, tuples, mapped types, and primitives;interfacecannot- Both can describe object shapes and be extended (interface via
extends, type via&) interfaceis generally preferred for public API contracts and library definitions (mergeability)typeis preferred for complex type operations, utility types, and union/intersection patterns
Question Variations
- “What is the difference between
interfaceandtypein TypeScript?” - “When would you prefer using a
typeover aninterface?” - “Explain the concept of ‘declaration merging’ and which keyword supports it.”
- “How do you extend an
interfacecompared to extending atypealias?”
Answers by Technology
+ Add VariantExpected Answer (PHP 8.5)
PHP has a structural difference in how it handles “types” compared to TypeScript:
- Interfaces: The primary way to define a contract. A class must explicitly
implementan interface. - Type Hinting: PHP uses native types (
string,int,bool,array,object) and class/interface names for type hinting. - Union & Intersection Types: PHP 8.0 introduced
string|int(Union) and PHP 8.1 introducedIterator&Countable(Intersection). - DNF Types (PHP 8.2): Disjunctive Normal Form allows combining unions and intersections, e.g.,
(A&B)|C.
Why It Matters
PHP is a dynamically typed language with an increasingly powerful static type system. Unlike TypeScript, PHP’s types are enforced at runtime. Understanding the difference between an Interface (a contract) and a Type Hint (a constraint) is key to writing modern, safe PHP.
Code Example
interface Logger {
public function log(string $message): void;
}
// Union Type Example
function process(string|int $input) {
// ...
}
// Intersection Type Example
function handle(Iterator&Countable $collection) {
echo count($collection);
}
Common Mistakes
- Confusing Type Hinting with Type Casting: Type hints enforce the type at the entry point of a function; they don’t automatically convert the data (unless strict_types is off and the data is compatible).
- Over-using
mixed: Using themixedtype hint defeats the purpose of the type system and should be avoided in favor of specific Union types.
Follow-up Questions
- What does
declare(strict_types=1);do? (Answer: It forces strict type checking for function calls, preventing the automatic coercion of types like ‘1’ into 1). - Can you define a “Type Alias” in PHP? (Answer: No, PHP does not have a
typekeyword. You must use interfaces or DTOs to represent complex shapes).
Expected Answer
Both interface and type can describe object shapes, but they differ in capabilities and intended use:
interface: Primarily used for defining the “contract” of an object. Its most unique feature is Declaration Merging, where multiple definitions of the same interface are combined into one.typealias: More versatile. It can define unions, intersections, primitives, tuples, and mapped types—none of which aninterfacecan do directly.
Why It Matters
Consistency and extensibility. Using interface for public APIs allows consumers to augment your types (e.g., adding a property to a library’s Request object). Using type is essential for complex type logic (unions, utility types) that makes TypeScript powerful. Mixing them without a strategy can lead to confusing codebases and blocked extension points.
Example Code
Interface: Extension & Merging
interface User {
id: string;
}
// Declaration Merging (Merged with the above)
interface User {
name: string;
}
interface Admin extends User {
role: 'admin';
}
Type: Unions & Intersections
type Result = Success | Error; // Union (Interface can't do this)
type Point = [number, number]; // Tuple
type Admin = User & { role: 'admin' }; // Intersection
Common Mistakes
- “Always use interface”: A common outdated rule.
typeis mandatory for unions, mapped types, and conditional types. - “Always use type”: This prevents consumers from using declaration merging, which is critical when writing libraries or augmenting global objects (like
windoworProcessEnv). - Confusing
extendswith&: While similar,extendsprovides better error messages by checking for compatibility, whereas&can silently result inneverif types conflict.
Follow-up Questions
- What happens when you intersect two types with conflicting properties? (Answer: The property type becomes
never. For example,{ x: string } & { x: number }results inx: never). - Can a class implement a
typealias? (Answer: Yes, as long as the type alias represents an object shape, not a union or a primitive).