TypeScript: Aliases de tipos no TypeScript (type)
Última atualização: 2026-08-26
Um alias de tipo atribui um nome a um tipo — ele não cria um novo tipo, mas simplesmente fornece a um tipo existente um nome mais curto e mais significativo.
1. Sintaxe básica dos aliases de tipo
(1) Tipos de nomenclatura
type ID = number;
type Name = string;
type Active = boolean;
let userId: ID = 42;
let userName: Name = "Charlie";
let isActive: Active = true;
(2) Aliases de tipos de objeto
type User = {
name: string;
age: number;
email: string;
};
let user: User = {
name: "Charlie",
age: 20,
email: "xiaoming@example.com"
};
type quanto interface podem definir a estrutura de um objeto— A sintaxe é um pouco diferente (type usa =, while interface, enquanto interface não usa), mas o efeito é praticamente o mesmo.
(3) Aliases de tipos de função
type GreetFunction = (name: string) => string;
let greet: GreetFunction = (name) => `Hello,${name}!`;
console.log(greet("Charlie")); // "Hello,Charlie!"
2. Aliases de tipos de união
tipo O uso mais comum — nomear tipos de união, o que melhora significativamente a legibilidade do código:
(1) Concatenação de strings
type Status = "pending" | "active" | "completed" | "cancelled";
type Role = "admin" | "editor" | "viewer";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
let orderStatus: Status = "pending";
let userRole: Role = "admin";
let method: HttpMethod = "GET";
(2) Convergência digital
type HttpStatus = 200 | 301 | 400 | 404 | 500;
type Bit = 0 | 1;
let code: HttpStatus = 200;
let flag: Bit = 1;
(3) Combinação híbrida
type Result = string | Error;
type Id = number | string | undefined;
let output: Result = "Success";
output = new Error("Failure"); // ✅ That's also legal
▶ Exemplo: Descrevendo respostas de API usando aliases de tipo
type ApiResponse<T> = {
status: number;
message: string;
data: T;
};
type User = {
id: number;
name: string;
email: string;
};
type UserResponse = ApiResponse<User>;
let response: UserResponse = {
status: 200,
message: "Achieve Success",
data: { id: 1, name: "Charlie", email: "xiao@example.com" }
};
console.log(`Status:${response.status}`);
console.log(`User:${response.data.name}`);
Saída:
Status:200
User:Charlie
3. Aliases do tipo cruzado
O tipo de interseção utiliza & para combinar vários tipos em um único — o novo tipo possui todas as propriedades de cada um dos tipos originais:
(1) Sintaxe básica
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
let person: Person = {
name: "Charlie",
age: 20
// Both must be present name and age
};
(2) Aplicações práticas — Habilidades combinadas
type HasId = { id: number };
type Timestamped = { createdAt: Date; updatedAt: Date };
type SoftDeletable = { deletedAt: Date | null };
type Entity = HasId & Timestamped & SoftDeletable;
let article: Entity = {
id: 1,
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: null
};
(3) Conflito cruzado
Quando dois tipos possuem propriedades com o mesmo nome, mas são de tipos diferentes, o resultado da interseção é never:
type A = { value: string };
type B = { value: number };
type C = A & B;
// C 's value The type is string & number = never
// No value can be both string and number
let c: C = { value: "" }; // ❌ You cannot string Assigned never
4. Aliases de tipos de tuplas
type Point = [x: number, y: number];
type KeyValuePair = [key: string, value: number];
type RGB = [red: number, green: number, blue: number];
let coord: Point = [10, 20];
let entry: KeyValuePair = ["score", 95];
let color: RGB = [255, 128, 0];
// Deconstruction
let [x, y] = coord;
let [key, val] = entry;
5. Tipos de literais de modelo
O TypeScript 4.1 introduziu os tipos de literais de modelo — concatenação de strings no nível do tipo:
(1) Sintaxe básica
type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// Results:"onClick" | "onFocus" | "onBlur"
type CSSProperty = "margin" | "padding";
type CSSDirection = "top" | "right" | "bottom" | "left";
type CSSRule = `${CSSProperty}-${CSSDirection}`;
// Results:"margin-top" | "margin-right" | ... | "padding-left"
(2) Tipos de operações com cadeias de caracteres integrados
| Tipo | Função | Exemplo |
|---|---|---|
Uppercase<S> |
Tudo em maiúsculas | Uppercase<"hello"> → "HELLO" |
Lowercase<S> |
tudo em minúsculas | Lowercase<"HELLO"> → "hello" |
Capitalize<S> |
Colocar a primeira letra em maiúscula | Capitalize<"hello"> → "Hello" |
Uncapitalize<S> |
inicial em minúscula | Uncapitalize<"Hello"> → "hello" |
▶ Exemplo: Um sistema de eventos com segurança de tipos
type EventType = "click" | "change" | "submit";
type HandlerName = `on${Capitalize<EventType>}`;
// "onClick" | "onChange" | "onSubmit"
interface EventHandlers {
onClick?: (x: number, y: number) => void;
onChange?: (value: string) => void;
onSubmit?: (data: FormData) => void;
}
// Usage——handler Type hints for names,I won't spell it wrong
let handlers: EventHandlers = {
onClick: (x, y) => console.log(`Click:(${x}, ${y})`),
onChange: (value) => console.log(`Value change:${value}`)
};
Saída:
// Executed successfully
6. Uma comparação abrangente de tipos e interfaces
(1) Comparação de recursos
| Capacidade | tipo | interface |
|---|---|---|
| Tipo de objeto | ✅ type T = { ... } |
✅ interface T { ... } |
| Tipo de composto | ✅ type T = A | B |
❌ |
| Tipo cruzado | ✅ type T = A & B |
Use extends em vez disso |
| Aliases para tipos básicos | ✅ type T = string |
❌ |
| Tipo de tupla | ✅ type T = [A, B] |
❌ |
| Literal de modelo | ✅ type T = \...`` |
❌ |
| Instruções de junção | ❌ | ✅ |
| classe implementa | ✅ | ✅ |
| estende | utiliza & | ✅ extends |
| Chave da propriedade calculada | ✅ [K in Keys] |
❌ |
(2) Selecione uma estratégia
Required Features → Select
───────────────────────────────
Composite Types A | B → type
Aliases for Basic Types → type
Tuple [A, B] → type
Template Literal Types → type
Object Shape + Inheritance Required → interface
Object Shape + Statement Merger → interface
Simple Object Shapes → Either is fine,As long as the team is on the same page, that's fine.
▶ Exemplo: Tipos literais de modelo para rotas type-safe
type Method = "GET" | "POST" | "PUT" | "DELETE";
type Resource = "users" | "posts" | "comments";
type ApiEndpoint = `${Method} /api/${Resource}`;
// Valid values: "GET /api/users", "POST /api/posts", etc.
let endpoint: ApiEndpoint = "GET /api/users";
// Invalid — caught at compile time
// endpoint = "PATCH /api/users"; // ❌ PATCH not in Method
// endpoint = "GET /api/orders"; // ❌ orders not in Resource
type EventName = "click" | "focus";
type HandlerName = `on${Capitalize<EventName>}`;
// "onClick" | "onFocus"
let handler: HandlerName = "onClick";
console.log(handler);
Saída:
onClick
❓ Perguntas Frequentes
P: O
typepode usar oextendspara herança? R: Otypenão possui uma sintaxeextends, mas é possível obter um efeito semelhante usando tipos cruzados&—type Child = Parent & { extra: string }. A sintaxeextendseminterfaceé mais clara e permite detectar conflitos; quando há conflito entre tipos cruzados, é gerado umneverem vez de um erro (o tipo simplesmente fica indisponível).
P: Um
typepode ser implementado por umclass? R: Sim. Desde que otypedefina um tipo de objeto (excluindo uniões, tipos primitivos etc.), umclasspode implementá-lo.class User implements UserType { ... }é totalmente válido.
P: Quando é preciso usar
typeem vez deinterface? R: Existem três casos: (1) Tipos de união —interfacenão pode expressarA | B; (2) Tipos de tupla — embora seja possível usarinterface, isso é muito complicado; (3) Tipos de literais de modelo —interfacenão os suporta. Em todos os outros casos, os dois são equivalentes, e você pode usar qualquer um deles.
P: Quais são os usos práticos dos tipos de literais de modelo? R: Eles são usados principalmente para programação de tipos avançada — como a geração automática de nomes de eventos (onClick/onFocus), a combinação de propriedades CSS (margin-top) e a inferência de tipos de caminhos de roteamento. Não são comumente utilizados no desenvolvimento cotidiano, mas são muito poderosos na definição de tipos para frameworks e bibliotecas. Iniciantes devem apenas estar cientes de sua existência.
📖 Resumo
- tipo: Atribui um alias a um tipo existente; não cria um novo tipo; sintaxe:
type Name = type - Os aliases de tipos de união são o uso mais comum do
type— eles tornam os tipos de união complexos mais legíveis e reutilizáveis. - Tipo Cruzado
A & BCombina todas as propriedades de vários tipos; em caso de conflito, o resultado é “nunca” - Os tipos de literais de modelo concatenam cadeias de caracteres no nível do tipo, em conjunto com operações embutidas (como Uppercase)
typeeinterfacesão equivalentes na maioria dos casos; tipos de união, tuplas e literais de modelo devem usartype
📝 Exercícios
- Problema básico (Dificuldade ⭐): Defina
StatusCode = 200 | 404 | 500usandotypee, em seguida, definaApiResponse<T> = { code: StatusCode; data: T }. Crie uma instância deApiResponse<string>e imprima-a. - Problema avançado (Dificuldade ⭐⭐): Use as combinações do tipo cruzado
HasId,HasTimestampseHasAuditpara definir um tipo completoEntity. Crie um objeto de instância e certifique-se de que todas as propriedades sejam atendidas. - Desafio (Dificuldade: ⭐⭐⭐): Defina
CSSDirection = "top" | "right" | "bottom" | "left"usando o tipo de literal de modelo e, em seguida, gereMarginStyle = { [K inmargin-${CSSDirection}]: number }. Verifique se o tipo gerado inclui propriedades como marginTop e marginRight.