TypeScript é um superset de JavaScript que têm sido cada vez mais usado pela comunidade, muitas novas funcionalidades e o decorrer dos updates da ferramenta a diferença entre types e interfaces vêm diminuindo gradativamente, porém ainda existem cenários ideais para se utilizar um ou outro.
Neste post vou tentar esclarecer um pouco o assunto e te ajudar a decidir entre tipos e interfaces em seus projetos.
Principais Funcionalidades
Bora dar uma olhada nas principais características e funcionalidades dos tipos e das interfaces e compararmos sua utilização.
Interfaces
Ideais para definir a estrutura de um objeto ou classes, as interfaces são ótimas para desenvolver um projeto aberto para implementações e extensões de comportamento.
interface VerifyToken {
(token: string): boolean;
}
interface AuthContext {
authToken: string;
verifyToken: VerifyToken;
}
const authContext: AuthContext = {
authToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
verifyToken: (token) => token.length === 36,
}
- Podem ser implementadas por classes: Interfaces podem definir estruturas genéricas que podem ser reutilizadas na construção de classes e objetos.
interface Person {
name: string;
};
class User implements Person {
name = 'John Doe';
};
const user: Person = {
name: 'John Doe',
};
- São extensíveis: Você pode extender interfaces na declaração de outras interfaces.
interface Person {
name: string;
};
interface User extends Person {
address: string;
};
const user: User = {
name: 'John Doe',
address: 'Brazil',
};
- Permitem declaration merging: Declaration merging é uma forma de extender uma interface, porém de forma menos explícita.
interface Person {
name: string;
};
interface Person {
age: number;
};
const person: Person = {
name: 'John Doe',
age: 20,
};
Types
Apesar de não poderem ser utilizados em definições de classes, os types são ferramentas poderosas que permitem funcionalidades e combinações avançadas de estruturas, além de adicionar segurança na tipagem de primitivos, funções e objetos.
type Token = string;
type VerifyToken = (token: Token) => boolean;
type AuthContext = {
authToken: Token;
verifyToken: VerifyToken;
}
const authContext: AuthContext = {
authToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
verifyToken: (token) => token.length === 36,
}
- Permitem intersections e unions: Pode-se considerar uma das maiores funcionalidades dos type aliases, as intersections e unions permitem combiná-los de várias formas.
type Person = {
name: string;
}
type Young = {
hungry: boolean;
};
type User = Person & { address: string };
type Me = Person & Young;
const user: User = {
name: 'John Doe',
address: 'Brazil',
};
const me: Me = {
name: 'Vinicius',
hungry: true,
};
type Car = {
wheels: 4
}
type Motorcycle = {
wheels: 2
}
let vehicle: Car | Motorcycle = {
wheels: 4,
} // Car
vehicle = {
wheels: 2,
} // Motorcycle
vehicle = {
wheels: 1,
} // Error
Afinal, como decidir?
A documentação do TypeScript deixa explícito que escolher entre type aliases e interfaces é algo muito relacionado ao gosto pessoal e necessidades do projeto, porém sugere utilizar interfaces até que você precise de alguma funcionalidade específica dos types.
É importante citar também, que para como bibliotecas e frameworks, é altamente sugerido utilizar interfaces para que sua API seja aberta para implementações e extensões de comportamento.
Fica claro que as maiores diferenças são em relação à forma de se declarar as estruturas, como por exemplo em funções, onde os types se mostram muito mais limpos e diretos ao ponto.
// Com Interfaces
interface HelloFunction {
(name: string): string;
}
const hello: HelloFunction = (name) => name;
// Com Types
type HelloFunction = (name: string) => string;
const hello: HelloFunction = (name) => name;
A combinação de types e interfaces na medida certa traz grandes benefícios, apesar de cada um ter seu caso de uso ideal, quando utilizados em conjunto eles podem abrir possibilidade para a utilização de features mais avançadas da linguagem.
- interfaces: definir estruturas de objetos e classes.
-
types: definir funções, utilizar funcionalidades mais avançadas como
conditional types
,type guards
, etc.
// https://www.typescriptlang.org/docs/handbook/2/conditional-types.html
interface Animal {
live(): void;
}
interface Dog extends Animal {
woof(): void;
}
type Example1 = Dog extends Animal ? number : string;
// ^ = type Example1 = number
type Example2 = RegExp extends Animal ? number : string;
// ^ = type Example2 = string
Espero que eu tenha conseguido esclarecer um pouco as coisas pra você, todos os exemplos que escrevi foram baseados na documentação oficial do TypeScript, a qual recomendo a leitura.
Top comments (0)