Array<Type> vs Type[] no TypeScript: a batalha de sintaxes que você precisa vencer
\n\nSe você já escreveu em TypeScript, com certeza já viu duas maneiras de declarar um array de números:
\n\nconst numbers1: number[] = [1, 2, 3];\nconst numbers2: Array<number> = [1, 2, 3];\n\nAmbas as opções funcionam. Ambas compilam. Ambas são TypeScript válido. Então por que tanta discussão em torno delas? Por que essa pergunta no Stack Overflow tem milhares de visualizações? E o principal — como não pisar em armadilhas que quebrarão seu projeto?
\n\nVamos entender de uma vez por todas. Sem teoria chata. Apenas o que realmente será útil na prática.
\n\nBreve introdução: o que é o quê
\n\nSintaxe Type[] (Array Literal Syntax)
\n\nEsta é a forma mais comum de declarar um array em TypeScript. Veio do JavaScript e parece natural:
\n\nlet fruits: string[] = ['apple', 'banana', 'cherry'];\nlet matrix: number[][] = [[1, 2], [3, 4]]; // Array de arrays\n\nCurto, legível, intuitivo. Para 90% dos casos, isso é suficiente.
\n\nSintaxe Array<Type> (Generic Syntax)
\n\nEsta é a forma genérica, usando a interface embutida Array<T>:
let fruits: Array<string> = ['apple', 'banana', 'cherry'];\nlet matrix: Array<Array<number>> = [[1, 2], [3, 4]];\n\nParece mais "acadêmico", mas oferece mais flexibilidade em cenários complexos.
\n\nTop 5 erros que até desenvolvedores experientes cometem
\n\nErro nº1: Confiança cega no autocomplete da IDE
\n\nSua IDE pode sugerir ambas as opções. Mas isso não significa que elas são intercambiáveis em todos os lugares. Veja um exemplo com union-types:
\n\n// Assim funciona\ntype Status = 'active' | 'inactive';\nconst statuses1: Status[] = ['active', 'inactive'];\n\n// Mas assim — erro de sintaxe!\n// const statuses2: Array<'active' | 'inactive'> = ['active', 'inactive']; \n// ❌ Erro: ';' expected\n\n// Versão correta com genérico:\nconst statuses3: Array<Status> = ['active', 'inactive'];\n\nConclusão: Dentro de Array<> não é possível usar union-types complexos diretamente. Primeiro, declare-os em um tipo separado.
Erro nº2: Confusão com arrays readonly
\n\nQuando você precisa tornar um array imutável, as sintaxes se comportam de forma diferente:
\n\n// ✅ Correto com Type[]\nconst readonlyFruits: readonly string[] = ['apple', 'banana'];\n// readonlyFruits.push('orange'); // ❌ Erro: readonly\n\n// ❌ Isso não funciona:\n// const wrong: readonly Array<string> = ['apple']; \n// Erro: 'readonly' modifier can only appear on array types\n\n// ✅ Correto com Array<> — use ReadonlyArray:\nconst correct: ReadonlyArray<string> = ['apple', 'banana'];\n\nConclusão: Para arrays readonly, use readonly Type[] ou ReadonlyArray<Type>. Não é possível misturar readonly com Array<>.
Erro nº3: Problemas com arrays multinível
\n\nQuando um array contém outros arrays, a sintaxe Array<> se torna verbosa:
// Legível e claro\nconst grid1: number[][] = [[1, 2], [3, 4]];\n\n// Já fica mais difícil de ler\nconst grid2: Array<Array<number>> = [[1, 2], [3, 4]];\n\n// E com três níveis? Um pesadelo:\nconst cube: Array<Array<Array<number>>> = [[[1]]]; // 🤯\n\n// Com Type[] é mais simples:\nconst cube2: number[][][] = [[[1]]];\n\nConclusão: Para arrays com mais de 2 níveis de aninhamento, use Type[][]. Seus colegas agradecerão.
Erro nº4: Ignorar o contexto de uso
\n\nEm alguns frameworks (Angular, React) e bibliotecas, um determinado estilo é adotado. Violar a convenção pode causar confusão:
\n\n// Angular frequentemente u