Siga as TypeScript melhores práticas - AWS Orientação prescritiva

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Siga as TypeScript melhores práticas

TypeScript é uma linguagem que amplia os recursos do JavaScript. É uma linguagem fortemente digitada e orientada a objetos. Você pode usar TypeScript para especificar os tipos de dados que estão sendo transmitidos em seu código e tem a capacidade de relatar erros quando os tipos não coincidem. Esta seção fornece uma visão geral das TypeScript melhores práticas.

Descreva seus dados

Você pode usar TypeScript para descrever a forma dos objetos e funções em seu código. Usar o tipo any é equivalente a optar por não verificar o tipo de uma variável. Recomendamos evitar usar anyem seu código. Aqui está um exemplo.

type Result = "success" | "failure" function verifyResult(result: Result) { if (result === "success") { console.log("Passed"); } else { console.log("Failed") } }

Use enumerações

É possível usar enumerações para definir um conjunto de constantes nomeadas e definir padrões que podem ser reutilizados em sua base de código. Recomendamos exportar suas enumerações uma vez em nível global e depois permitir que outras classes importem e usem as enumerações. Suponha que você queira criar um conjunto de ações possíveis para capturar os eventos em sua base de código. TypeScript fornece enumerações numéricas e baseadas em seqüências de caracteres. O exemplo a seguir usa uma enumeração.

enum EventType { Create, Delete, Update } class InfraEvent { constructor(event: EventType) { if (event === EventType.Create) { // Call for other function console.log(`Event Captured :${event}`); } } } let eventSource: EventType = EventType.Create; const eventExample = new InfraEvent(eventSource)

Use interfaces do

Uma interface é um contrato para a classe. Se você criar um contrato, os usuários deverão cumpri-lo. No exemplo a seguir, uma interface é usada para padronizar props e garantir que os chamadores forneçam o parâmetro esperado ao usar essa classe.

import { Stack, App } from "aws-cdk-lib"; import { Construct } from "constructs"; interface BucketProps { name: string; region: string; encryption: boolean; } class S3Bucket extends Stack { constructor(scope: Construct, props: BucketProps) { super(scope); console.log(props.name); } } const app = App(); const myS3Bucket = new S3Bucket(app, { name: "amzn-s3-demo-bucket", region: "us-east-1", encryption: false })

Algumas propriedades só podem ser modificadas quando um objeto é criado pela primeira vez. É possível especificar isso colocando readonly antes do nome da propriedade, conforme mostrado no exemplo a seguir.

interface Position { readonly latitude: number; readonly longitute: number; }

Estenda interfaces

A extensão de interfaces reduz a duplicação, pois não é necessário copiar as propriedades entre as interfaces. Além disso, o leitor do seu código pode entender facilmente os relacionamentos em sua aplicação.

interface BaseInterface{ name: string; } interface EncryptedVolume extends BaseInterface{ keyName: string; } interface UnencryptedVolume extends BaseInterface { tags: string[]; }

Evite interfaces vazias

Recomendamos evitar interfaces vazias devido aos riscos potenciais criados por elas. No exemplo a seguir, há uma interface vazia chamadaBucketProps. Os objetos myS3Bucket1 e myS3Bucket2 são ambos válidos, mas seguem padrões diferentes porque a interface não impõe nenhum contrato. O código a seguir compilará e imprimirá as propriedades, mas isso introduz inconsistências na aplicação.

interface BucketProps {} class S3Bucket implements BucketProps { constructor(props: BucketProps){ console.log(props); } } const myS3Bucket1 = new S3Bucket({ name: "amzn-s3-demo-bucket", region: "us-east-1", encryption: false, }); const myS3Bucket2 = new S3Bucket({ name: "amzn-s3-demo-bucket", });

Use fábricas

Em um padrão Abstract Factory, uma interface é responsável por criar uma fábrica de objetos relacionados sem especificar explicitamente suas classes. Por exemplo, você pode criar uma fábrica do Lambda para criar funções do Lambda. Em vez de criar uma nova função Lambda em sua construção, você está delegando o processo de criação à fábrica. Para obter mais informações sobre esse padrão de design, consulte Abstract Factory TypeScript na documentação do Refactoring.Guru.

Use desestruturação em propriedades

A desestruturação, introduzida em ECMAScript 6 (ES6), é um JavaScript recurso que permite extrair vários dados de uma matriz ou objeto e atribuí-los às suas próprias variáveis.

const object = { objname: "obj", scope: "this", }; const oName = object.objname; const oScop = object.scope; const { objname, scope } = object;

Defina convenções de nomenclatura padrão

A aplicação de uma convenção de nomenclatura mantém a base de código consistente e reduz a sobrecarga representada por pensar em como nomear uma variável. Recomendamos o seguinte:

  • Use camelCase para nomes de variáveis e funções.

  • Use PascalCase para nomes de classes e nomes de interface.

  • Use camelCase para membros da interface.

  • Use PascalCase para nomes de tipos e nomes de enumeração.

  • Nomeie arquivos com camelCase (por exemplo, ebsVolumes.tsx oustorage.tsb)

Não use a palavra-chave var

A let instrução é usada para declarar uma variável local em TypeScript. É semelhante à var palavra-chave, mas tem algumas restrições no escopo em comparação com a var palavra-chave. Uma variável declarada em um bloco com let só está disponível para uso dentro desse bloco. A var palavra-chave não pode ter escopo de bloco, o que significa que ela pode ser acessada fora de um bloco específico (representado por{}), mas não fora da função em que está definida. Você pode redeclarar e atualizar var variáveis. É uma prática recomendada evitar o uso da var palavra-chave.

Considere usar ESLint e Prettier

ESLintanalisa estaticamente seu código para encontrar problemas rapidamente. Você pode usar ESLint para criar uma série de afirmações (chamadas regras de lint) que definem a aparência ou o comportamento do seu código. ESLinttambém tem sugestões de correção automática para ajudar você a melhorar seu código. Finalmente, você pode usar ESLint para carregar regras de lint de plug-ins compartilhados.

O Prettier é um formatador de código conhecido compatível com toda uma variedade de linguagens de programação. O Prettier pode ser usado para definir seu estilo de código a fim de evitar sua formatação manual. Após a instalação, você pode atualizar seu arquivo package.json e executar os comandos npm run format e npm run lint.

O exemplo a seguir mostra como habilitar o ESLint formatador Prettier para seu AWS CDK projeto.

"scripts": { "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk", "lint": "eslint --ext .js,.ts .", "format": "prettier --ignore-path .gitignore --write '**/*.+(js|ts|json)'" }

Use modificadores de acesso

O modificador privado em TypeScript limita a visibilidade somente para a mesma classe. Ao adicionar o modificador privado a uma propriedade ou método, é possível acessar essa propriedade ou método dentro da mesma classe.

O modificador público permite que propriedades e métodos de classe sejam acessíveis de todos os locais. Se você não especificar nenhum modificador de acesso para propriedades e métodos, eles usarão o modificador público por padrão.

O modificador protegido permite que propriedades e métodos de uma classe sejam acessíveis dentro da mesma classe e dentro de subclasses. Use o modificador protegido quando você espera criar subclasses em seu AWS CDK aplicativo.

Use tipos de utilitários

Os tipos de utilitários em TypeScript são funções de tipo predefinidas que realizam transformações e operações em tipos existentes. Isso ajuda você a criar novos tipos com base nos tipos existentes. Por exemplo, você pode alterar ou extrair propriedades, tornar as propriedades opcionais ou obrigatórias ou criar versões imutáveis de tipos. Ao usar tipos de utilitários, você pode definir tipos mais precisos e capturar possíveis erros em tempo de compilação.

Parcial <Type>

Partialmarca todos os membros de um tipo de entrada Type como opcionais. Esse utilitário retorna um tipo que representa todos os subconjuntos de um determinado tipo. Veja a seguir um exemplo de Partial.

interface Dog { name: string; age: number; breed: string; weight: number; } let partialDog: Partial<Dog> = {};

Obrigatório <Type>

Requiredfaz o oposto dePartial. Isso torna todos os membros de um tipo de entrada Type não opcionais (em outras palavras, obrigatórios). Veja a seguir um exemplo de Required.

interface Dog { name: string; age: number; breed: string; weight?: number; } let dog: Required<Dog> = { name: "scruffy", age: 5, breed: "labrador", weight: 55 // "Required" forces weight to be defined };