Novidades do Angular 18.1

A versão 18.1 do framework Angular foi lançada recentemente (10/07/2024). Dentre as novidades, podemos destacar:

  • Declaração de variáveis diretamente no template com @let (developer preview)
  • Atualização para TypeScript 5.5
  • Uso de UrlTree como input no [routerLink]

Declarando variáveis no template com o @let

Com o @let, podemos declarar variáveis diretamente no template, o que traz benefícios como melhor legibilidade e simplificação do código. Veja o exemplo abaixo:

@if (carrosPorMarca$ | async; as carrosPorMarca) {
  @for (marca of carrosPorMarca | keyvalue; track marca.key) {
    <h1>{{marca.key}}</h1>
    <ul>
      @for (carro of marca.value; track $index) {
        <li>
          <strong>{{carro.modelo}}</strong>
          <div>{{carro.detalhes.ano}}</div>
          <div>{{carro.detalhes.preco | currency}}</div>
        </li>
      }
    </ul>
  }
} @else {
  <div>carregando...</div>
}

Pode ser reescrito para:

@let carrosPorMarca = carrosPorMarca$ | async;
@if (carrosPorMarca) {
  @for (marca of carrosPorMarca | keyvalue; track marca.key) {
    <h1>{{marca.key}}</h1>
    <ul>
      @let carros = marca.value;
      @for (carro of carros; track $index) {
        @let modelo = carro.modelo;
        @let ano = carro.detalhes.ano;
        @let preco = carro.detalhes.preco | currency;

        <li>
          <strong>{{modelo}}</strong>
          <div>{{ano}}</div>
          <div>{{preco}}</div>
        </li>
      }
    </ul>
  }
} @else {
  <div>carregando...</div>
}

Suporte ao TypeScript 5.5

O Angular v18.1 agora suporta TypeScript 5.5. Isso permite usar a versão mais recente do TypeScript em suas aplicações. Uma das novidades é a melhor detecção de mudanças nas variáveis ao longo do código. Veja o exemplo abaixo:

detalhesCarro(modelos: string[]) {
  const carros: Carro[] = [
    { modelo: 'Corolla', detalhes: { ano: 2021, preco: 20000 } },
    { modelo: 'Camry', detalhes: { ano: 2020, preco: 25000 } },
    { modelo: 'Model S', detalhes: { ano: 2021, preco: 80000 } },
    { modelo: 'Model 3', detalhes: { ano: 2020, preco: 35000 } },
  ];

  const modelosProcurados = modelos
    .map((modeloProcurado) =>
      carros.find((carro) => carro.modelo === modeloProcurado)
    )
    // a expressão acima retorna o tipo: (Carro | undefined)[]
    // então filtramos para retirar os não encontrados:
    .filter((a) => a !== undefined);

  for (const modeloProcurado of modelosProcurados) {
    // Antes do TypeScript 5.5 você pegaria o seguinte erro:
    //   'modeloProcurado' is possibly 'undefined'
    //
    // Para resolver, poderia modificar para:
    // console.log('Modelo encontrado: ', modeloProcurado?.modelo);

    console.log('Modelo encontrado: ', modeloProcurado.modelo);
  }
}

Abaixo há a lista completa com as novidades do TypeScript 5.5:

Announcing TypeScript 5.5 - TypeScript
Today we’re excited to announce the release of TypeScript 5.5! If you’re not familiar with TypeScript, it’s a language that builds on top of JavaScript by making it possible to declare and describe types. Writing types in our code allows us to explain intent and have other tools check our code to catch mistakes like typos,

Até então a diretiva [routerLink] aceitava como entrada os tipos string e any[]. A partir desta versão (18.1) também podemos utilizar o tipo UrlTree:

@Component({ ... })
export class ExemploComponent {
  linkExemplo = inject(Router).createUrlTree(["/carros", 1, 'detalhes']);
}
<button
  role="link"
  [routerLink]="['carros', 1, 'detalhes']">Link</button>

ou podemos passar o tipo UrlTree

<button
  role="link"
  [routerLink]="linkExemplo">Link</button>

Considerações

Neste pequeno texto passei somente por algumas das novidades. Abaixo deixo um link com a lista completa da versão 18.1 do Angular:

Release v18.1.0 · angular/angular
18.1.0 (2024-07-10) common Commit Description typo in NgOptimizedImage warning (#56756) typo in warning for NgOptimizedDirective (#56817) compiler Commit Description Add exten…