TypeScript type vs interface – What is the difference?
TypeScript, a superset of JavaScript, introduces powerful static typing capabilities to the dynamic world of JavaScript. A core part of TypeScript's typing system revolves around two primary constructs: type
and interface
. Both offer ways to define and enforce shapes of objects, but each has its unique capabilities, use cases, and limitations. Let's dive deep into understanding them.
Understanding 'Type' in TypeScript
TypeScript's type
provides a way to define and give a name to specific shapes of data, be it primitive types, union types, intersection types, and more. It's a fundamental aspect of the TypeScript type system, which allows developers to create more robust and error-free code.
Definition and Basic Syntax
To declare a type, one uses the type
keyword followed by the name of the type and its definition:
type Age = number; type FullName = string;
Features of 'Type'
TypeScript's type
has various unique features that cater to a myriad of use cases.
Union Types
Union types allow us to represent values that can be of multiple types:
type StringOrNumber = string | number;
With this type, a variable can either be a string or a number.
Intersection Types
Intersection types are a way of combining multiple types:
type NameAndAge = { name: string } & { age: number };
Tuple Types
Tuple types represent arrays where the type of a fixed number of elements is known:
type UserTuple = [string, number]; // [name, age]
Mapped Types and Conditional Types
Mapped types help to create new types based on existing ones:
type Readonly<T> = { readonly [P in keyof T]: T[P] };
Conditional types allow types to be chosen based on conditions:
type IsString<T> = T extends string ? true : false;
Limitations and Use Cases
While type
is powerful, it has its limitations. For example, you cannot define method implementations inside a type or declare the same type multiple times. type
is ideal for union and intersection types, tuples, and when you need to create derived types.
Understanding 'Interface' in TypeScript
Interfaces in TypeScript serve as a powerful way to define contracts for your code and ensure adherence to specific shapes or forms of data. They primarily define the shape of object literals, classes, and function types.
Definition and Basic Syntax
Declaring an interface is done using the interface
keyword:
interface User { name: string; age: number; }
Features of 'Interface'
Interfaces offer a range of unique capabilities different from types.
Extending Interfaces
Interfaces can extend other interfaces, creating a chain of inherited properties:
interface Employee extends User { employeeId: number; }
Implementing Interfaces in Classes
Classes in TypeScript can implement interfaces, ensuring they adhere to the shape defined by the interface:
class MyUser implements User { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }
In summary, both type
and interface
offer unique tools to shape and enforce data structures in TypeScript. Their appropriate usage can lead to clearer, safer, and more maintainable code. For an in-depth exploration of these constructs, the official TypeScript documentation is an invaluable resource.
Optional Properties in Interfaces
In TypeScript, interfaces allow you to define the shape of an object. At times, not all properties of an interface might be required. This is where optional properties come into play. They are marked with a ?
at the end of the property name:
interface Profile { firstName: string; lastName?: string; }
In the above Profile
interface, firstName
is a required property, while lastName
is optional.
Readonly Properties
TypeScript provides a readonly
modifier for properties to make sure they are not modified after creation. When a property is marked as readonly
, it can only be initialized once and cannot be reassigned later.
interface Point { readonly x: number; readonly y: number; }
With this Point
interface, once a point object is created, its x
and y
values cannot be changed.
Index Signatures
There are situations where you might not know the keys of an object ahead of time. Index signatures come to the rescue:
interface StringArray { [index: number]: string; }
Here, the StringArray
interface describes arrays where the index is a number, and the value is a string.
Method Signatures in Interfaces
Interfaces can also define methods:
interface Greet { greet(name: string): string; }
This Greet
interface expects an implementing object to have a greet
method that takes a string argument and returns a string.
Extending Classes with Interfaces
Interestingly, interfaces can extend classes. When an interface extends a class, it inherits the members of the class but not their implementations.
class Control { private state: any; } interface SelectableControl extends Control { select(): void; }
Any class that implements SelectableControl
must have a select
method and also be a subclass of Control
.
Advantages and Limitations
Advantages:
- Interfaces are great for declaring the shapes of objects or classes.
- They support declaration merging, where multiple interface declarations with the same name get automatically merged.
Limitations:
- They can't represent union or tuple types.
- Interface declarations only exist at compile-time and have zero runtime JS impact.
Comparing 'Type' and 'Interface'
TypeScript offers two primary ways to define shapes: type
and interface
.
Similarities
- Both
type
andinterface
can be used to describe the shape of an object or function. - Both support intersection and union (though differently).
Differences
Syntax and Declaration
type
has a more flexible syntax and can represent a wider range of shapes, including primitives, union, and tuple types:
type Name = string | string[];
On the other hand, interfaces are restricted to representing object shapes:
interface Person { name: string; }
Extensibility
Interfaces are more extensible. Multiple interfaces with the same name are automatically merged:
interface Box { height: number; } interface Box { width: number; }
For type
, you'd use intersection:
type Box = Height & Width;
Class Implementation
Classes can implement interfaces using the implements
keyword:
class User implements Person { name: string; }
However, classes cannot implement type
.
Other Notable Differences
type
can represent primitives likestring
,number
, etc., while interfaces cannot.type
aliases are not extensible after being created.
Performance Considerations
Both type
and interface
are TypeScript constructs and don't exist at runtime. However, interfaces are slightly more performant at compile time, especially when reused multiple times.
Best Practices and Recommendations
When to use 'Type'
- When you need union, tuple, or other complex types.
- When you need type transformations, e.g.,
Partial<T>
orReadonly<T>
.
When to use 'Interface'
- For declaring object shapes, especially for objects like function types or classes.
- When you need declaration merging.
Combining type and interface
Both can be used in harmony, such as using type
for utility operations and interface
for object shapes.
Real-world Examples and Use Cases
- Using
interface
to define data models in an API client. - Utilizing
type
for configuration settings that can have multiple valid forms.
Conclusion
Both type
and interface
are powerful tools in the TypeScript toolbox. Depending on the use-case and requirements, one might be preferable over the other.
Additional Resources
For more insights and deeper understanding, refer to the official TypeScript documentation. It provides a wealth of information, examples, and guides on these topics.
Sharing is caring
Did you like what Rishabh Rao wrote? Thank them for their work by sharing it on social media.
No comments so far
Curious about this topic? Continue your journey with these coding courses: