DEV Community

Cover image for Principais diferenças entre types e interfaces em TypeScript
Vinícius Estevam
Vinícius Estevam

Posted on

Principais diferenças entre types e interfaces em TypeScript

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,
}
Enter fullscreen mode Exit fullscreen mode
  • 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',
};
Enter fullscreen mode Exit fullscreen mode
  • 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',
};
Enter fullscreen mode Exit fullscreen mode
  • 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,
};
Enter fullscreen mode Exit fullscreen mode

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,
}
Enter fullscreen mode Exit fullscreen mode
  • 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,
};
Enter fullscreen mode Exit fullscreen mode
type Car = {
  wheels: 4
}

type Motorcycle = {
  wheels: 2
}

let vehicle: Car | Motorcycle = {
  wheels: 4,
} // Car

vehicle = {
  wheels: 2,
} // Motorcycle

vehicle = {
  wheels: 1,
} // Error
Enter fullscreen mode Exit fullscreen mode

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; 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

https://www.typescriptlang.org/docs/handbook/

Top comments (0)