Prática de aplicação do TypeScript no desenvolvimento front-end

Prática de aplicação do TypeScript no desenvolvimento front-end

O TypeScript se tornou a ferramenta preferida de cada vez mais desenvolvedores na área de desenvolvimento front-end. É um superconjunto de tipo estático, lançado pela Microsoft, que fornece aos desenvolvedores uma poderosa verificação de tipo estático, programação orientada a objetos e recursos de desenvolvimento modular, e resolve alguns problemas causados ​​pelo recurso de tipo dinâmico do JavaScript.

Nesta postagem do blog, vamos nos aprofundar na prática de aplicação do TypeScript no desenvolvimento front-end. Abordaremos os fundamentos do TypeScript, incluindo tipos de dados, funções, classes e programação orientada a objetos, bem como desenvolvimento modular. Conhecer esses fundamentos ajudará os desenvolvedores a entender melhor como o TypeScript funciona e seus benefícios. Resumiremos o conteúdo deste artigo, enfatizando a importância e o valor de aplicação prática do TypeScript no desenvolvimento front-end. Por meio do estudo deste post do blog, os leitores poderão entender completamente o TypeScript e aprender como aplicá-lo na prática para melhorar a eficiência e a qualidade do código do desenvolvimento front-end.

Vamos explorar a prática de aplicação do TypeScript no desenvolvimento front-end e aprimorar nossa capacidade técnica e nível de desenvolvimento!

1. Conhecimento básico de TypeScript

1.1 Tipos de Dados

1.1.1 Tipos de dados primitivos

No TypeScript, os tipos de dados primitivos incluem:

  1. number: Representa valores numéricos, incluindo inteiros e números de ponto flutuante.
  2. string: Indica texto, entre aspas simples ou duplas.
  3. boolean: Representa um valor booleano, que pode ser trueou false.
  4. null: Indica um valor nulo.
  5. undefined: Indica um valor indefinido.
  6. symbol: Representa um valor exclusivo, usado para criar uma propriedade de objeto exclusiva.

aqui estão alguns exemplos:

let age: number = 25;
let name: string = "John";
let isReady: boolean = true;
let value: null = null;
let data: undefined = undefined;
let id: symbol = Symbol("id");

1.1.2 Arrays e tuplas

No TypeScript, além dos tipos de dados primitivos, você também pode usar arrays e tuplas para lidar com coleções de vários valores.

tipo de matriz

Uma matriz é uma coleção de valores do mesmo tipo. No TypeScript, os tipos de matriz podem ser representados de duas maneiras:

  1. 类型[]: Use um tipo seguido por um colchete, indicando que somente os elementos do tipo especificado podem ser armazenados na matriz.
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["John", "Jane", "Alice"];
  1. Array<类型>: Use Arrayuma palavra-chave seguida de colchetes angulares, onde o tipo de elemento é especificado nos colchetes angulares.
let numbers: Array<number> = [1, 2, 3, 4, 5];
let names: Array<string> = ["John", "Jane", "Alice"];

Você pode usar o índice para acessar os elementos na matriz e executar operações como percorrer a matriz, adicionar ou remover elementos.

tipo de tupla

Uma tupla é uma representação de uma matriz de tipo conhecido e comprimento fixo. No TypeScript, os tipos de tupla podem ser definidos usando:

let person: [string, number] = ["John", 25];

No exemplo acima, personé uma matriz com comprimento 2, o primeiro elemento é um tipo string (nome) e o segundo elemento é um tipo numérico (idade). Cada elemento na tupla pode ter um tipo diferente.

Você pode usar o índice para acessar os elementos na tupla e executar operações como atribuição de desestruturação e travessia na tupla.

O uso de arrays e tuplas permite uma melhor organização e manipulação de coleções de múltiplos valores e fornece segurança de tipo e legibilidade de código. No desenvolvimento real, escolha usar arrays ou tuplas para representar e operar diferentes tipos de coleta de dados de acordo com as necessidades.

1.1.3 Objetos e interfaces

No TypeScript, objetos e interfaces são conceitos importantes para lidar com tipos de dados complexos.

Tipo de objeto

Um objeto é uma coleção de propriedades, cada uma com um par chave-valor. No TypeScript, os tipos de objeto podem ser representados das seguintes maneiras:

let person: {
    
     name: string, age: number } = {
    
     name: "John", age: 25 };

No exemplo acima, personé um objeto com dois atributos: nameum tipo string agee um tipo número.

Os tipos de objeto podem definir estruturas complexas, como métodos e objetos aninhados.

interface

Uma interface é um tipo de dado abstrato que define a estrutura e o comportamento de um objeto. O uso de interfaces pode melhorar a legibilidade, manutenção e reutilização do código. No TypeScript, as interfaces podem ser declaradas usando:

interface Person {
    
    
  name: string;
  age: number;
}

let person: Person = {
    
     name: "John", age: 25 };

No exemplo acima, Persona interface define a estrutura de um objeto, incluindo namepropriedades (tipo string) e ageatributos (tipo number). Ao especificar o tipo de um objeto como Personuma interface, garantimos que o objeto esteja em conformidade com a estrutura definida pela interface.

A interface também oferece suporte a recursos avançados, como atributos opcionais, atributos somente leitura e tipos de função, tornando a interface mais flexível e poderosa.

Ao usar objetos e interfaces, podemos descrever e manipular melhor tipos de dados complexos e aumentar a legibilidade e a manutenção do código. No desenvolvimento real, escolha uma maneira apropriada de representar e processar os dados do tipo de objeto de acordo com os requisitos e o design.

1.2 Funções

1.2.1 Definição de função e tipo de parâmetro

No TypeScript, podemos usar funções de seta ( =>) ou palavras-chave functionpara definir funções. Ao mesmo tempo, também podemos especificar tipos para os parâmetros da função.

// 箭头函数
const add = (x: number, y: number): number => {
    
    
  return x + y;
};

// function 关键字
function multiply(x: number, y: number): number {
    
    
  return x * y;
}

No exemplo acima, as funções adde both multiplytêm dois parâmetros, e os tipos de parâmetro são ambos number. Todos eles retornam um numbertipo de resultado.

1.2.2 Tipo e voidtipo de retorno da função

As funções também podem especificar um tipo de retorno. Os tipos podem ser usados ​​se a função não retornar nenhum valor void.

function sayHello(name: string): void {
    
    
  console.log(`Hello, ${
      
      name}!`);
}

function calculateSum(x: number, y: number): number {
    
    
  return x + y;
}

No exemplo acima, a função sayHellonão tem valor de retorno, então o tipo de retorno é void. Considerando que a função calculateSumretorna a soma dos dois argumentos, o tipo de retorno é number.

1.3 Classes e Programação Orientada a Objetos

1.3.1 Definição de classe e construtor

No TypeScript, classas classes podem ser definidas usando palavras-chave. Classe é um conceito central da programação orientada a objetos, que é usada para descrever objetos com as mesmas propriedades e métodos.

class Person {
    
    
  name: string;
  age: number;

  constructor(name: string, age: number) {
    
    
    this.name = name;
    this.age = age;
  }

  sayHello(): void {
    
    
    console.log(`Hello, my name is ${
      
      this.name}.`);
  }
}

No exemplo acima, Persona classe define namee ageduas propriedades e possui um sayHellométodo. Os construtores constructorexecutam operações de inicialização ao instanciar uma classe.

Palavras-chave podem ser usadas para newinstanciar uma classe e acessar suas propriedades e métodos.

let person = new Person("John", 25);
console.log(person.name); // 输出:John
person.sayHello(); // 输出:Hello, my name is John.

1.3.2 Herança e polimorfismo

A herança é um conceito importante na programação orientada a objetos, que permite que novas classes sejam derivadas de classes existentes e herdem as propriedades e métodos da classe pai. No TypeScript, você pode usar extendspalavras-chave para implementar a herança entre as classes.

class Student extends Person {
    
    
  studentId: string;

  constructor(name: string, age: number, studentId: string) {
    
    
    super(name, age);
    this.studentId = studentId;
  }

  study(): void {
    
    
    console.log(`${
      
      this.name} is studying.`);
  }
}

No exemplo acima, Studenta classe herda da Personclasse e adiciona uma studentIdpropriedade e um studymétodo.

Por meio da herança, as subclasses podem reutilizar as propriedades e métodos da classe pai e podem personalizar novas propriedades e métodos.

let student = new Student("John", 20, "12345");
console.log(student.name); // 输出:John
student.sayHello(); // 输出:Hello, my name is John.
student.study(); // 输出:John is studying.

O polimorfismo é um conceito importante na programação orientada a objetos, que permite que diferentes objetos implementem diferentes implementações do mesmo método. No TypeScript, o polimorfismo pode ser obtido por meio da reescrita de métodos.

class Animal {
    
    
  sound(): void {
    
    
    console.log("The animal makes a sound.");
  }
}

class Dog extends Animal {
    
    
  sound(): void {
    
    
    console.log("The dog barks.");
  }
}

class Cat extends Animal {
    
    
  sound(): void {
    
    
    console.log("The cat meows.");
  }
}

let animal: Animal = new Animal();
animal.sound(); // 输出:The animal makes a sound.

let dog: Animal = new Dog();
dog.sound(); // 输出:The dog barks.

let cat: Animal = new Cat();
cat.sound(); // 输出:The cat meows.

No exemplo acima, Animalé uma classe base Doge Caté sua subclasse. Ambos têm um soundmétodo chamado , mas cada subclasse implementa esse método de maneira diferente.

Ao declarar o objeto como um tipo de classe base, o polimorfismo pode ser alcançado.Mesmo que o tipo específico seja uma subclasse, o método definido na classe base pode ser chamado para executar diferentes comportamentos de acordo com o tipo real do objeto.

1.3.3 Modificadores de acesso (público, privado, protegido)

Os modificadores de acesso são usados ​​para controlar o acesso aos membros da classe, pelo qual eles podem restringir a acessibilidade dos membros.

  • public: O modificador de acesso padrão, indicando que o membro pode ser acessado em qualquer lugar.
  • private: Indica que o membro só pode ser acessado dentro da classe em que está definido.
  • protected: Indica que o membro está acessível na classe em que está definido e suas subclasses.
class Person {
    
    
  public name: string;
  private age: number;
  protected gender: string;

  constructor(name: string, age: number, gender: string) {
    
    
    this.name = name;
    this.age = age;
    this.gender = gender;
  }
}

No exemplo acima, namea propriedade é pública e pode ser acessada de qualquer lugar. ageUma propriedade é privada e só pode ser acessada dentro da classe em que está definida. genderUma propriedade é protegida e pode ser acessada na classe em que está definida e em suas subclasses.

Modificadores de acesso também podem ser aplicados a métodos de classes.

class Person {
    
    
  public sayHello(): void {
    
    
    console.log("Hello!");
  }

  private whisperSecret(): void {
    
    
    console.log("This is a secret.");
  }

  protected showAge(): void {
    
    
    console.log("I am 25 years old.");
  }
}

No exemplo acima, sayHelloo método possui um modificador de acesso público e pode ser chamado de qualquer lugar. whisperSecretOs métodos têm um modificador de acesso privado e só podem ser chamados de dentro da classe. showAgeUm método tem um modificador de acesso protegido e pode ser chamado na classe em que é definido e em suas subclasses.

let person = new Person();
person.sayHello(); // 输出:Hello!

// Error: Property 'whisperSecret' is private and only accessible within class 'Person'.
person.whisperSecret();

// Error: Property 'showAge' is protected and only accessible within class 'Person' and its subclasses.
person.showAge();

Por meio de modificadores de acesso, você pode controlar o escopo de acesso de atributos e métodos, melhorar o encapsulamento e a segurança do código e permitir que as subclasses sejam herdadas e reescritas quando necessário.

1.4 Programação modular

1.4.1 Módulos de importação e exportação

No TypeScript, você pode usar programação modular para organizar e gerenciar seu código. Módulos são unidades independentes de código que podem conter variáveis, funções, classes, etc.

módulo de exportação: para exportar variáveis, funções, classes ou outras definições dentro de um módulo, você pode usar exporta palavra-chave.

export const PI = 3.14;

export function double(num: number): number {
    
    
  return num * 2;
}

export class Circle {
    
    
  radius: number;

  constructor(radius: number) {
    
    
    this.radius = radius;
  }

  getArea(): number {
    
    
    return Math.PI * this.radius ** 2;
  }
}

No exemplo acima, as constantes, funções e classes são exportadas como a interface pública do módulo por meio exportda palavra-chave .PIdoubleCircle

módulo de importação: Para usar uma variável, função ou classe exportada em outro módulo, você pode usar importa palavra-chave import.

import {
    
     PI, double, Circle } from "./math";

console.log(PI); // 输出:3.14

console.log(double(5)); // 输出:10

let circle = new Circle(3);
console.log(circle.getArea()); // 输出:28.26

No exemplo acima, constantes, funções e classes são importadas importdo módulo usando palavras-chave . Eles podem então ser usados ​​no módulo atual../mathPIdoubleCircle

1.4.2 Diferença entre namespace e módulo

Tanto os namespaces quanto os módulos são usados ​​para organizar e gerenciar o código, mas possuem algumas diferenças.

Namespaces: é uma maneira de organizar o código no escopo global para evitar conflitos de nomenclatura. namespaceUm namespace pode ser definido por palavras-chave.

namespace MyNamespace {
    
    
  export const PI = 3.14;

  export function double(num: number): number {
    
    
    return num * 2;
  }

  export class Circle {
    
    
    radius: number;

    constructor(radius: number) {
    
    
      this.radius = radius;
    }

    getArea(): number {
    
    
      return Math.PI * this.radius ** 2;
    }
  }
}

No exemplo acima, MyNamespaceé um namespace, que contém PIconstantes, doublefunções e Circleclasses.

Para usar o conteúdo de um namespace em outro namespace ou módulo, você pode acessá-lo usando o nome do namespace.

console.log(MyNamespace.PI); // 输出:3.14

console.log(MyNamespace.double(5)); // 输出:10

let circle = new MyNamespace.Circle(3);
console.log(circle.getArea()); // 输出:28.26

módulo: é a maneira recomendada de organizar o código em TypeScript, que fornece encapsulamento mais forte e reutilização de código. moduleUm módulo pode ser definido por palavras-chave.

// math.ts
export const PI = 3.14;

export function double(num: number): number {
    
    
  return num * 2;
}

export class Circle {
    
    
  radius: number;

  constructor(radius: number) {
    
    
    this.radius = radius;
  }

  getArea(): number {
    
    
    return Math.PI * this.radius ** 2;
  }
}

No exemplo acima, math.tsé um módulo que contém PIconstantes, doublefunções e Circleclasses.

Para usar o conteúdo de um módulo em outro módulo, você pode usar importa palavra-chave import.

// app.ts
import {
    
     PI, double, Circle } from "./math";

console.log(PI); // 输出:3.14

console.log(double(5)); // 输出:10

let circle = new Circle(3);
console.log(circle.getArea()); // 输出:28.26

Em comparação com os namespaces, os módulos são mais flexíveis e extensíveis e suportam recursos mais modulares, como importações e exportações, exportações padrão, etc. Como tal, os módulos são a maneira mais comum e recomendada de organizar o código no TypeScript.

Resumir

Ambos os namespaces e módulos podem ser usados ​​para organizar e gerenciar o código, mas eles têm algumas diferenças:

  • Os namespaces são uma forma de organizar o código no escopo global para evitar conflitos de nomenclatura.
  • Os módulos são a maneira recomendada de organizar o código no TypeScript, fornecendo encapsulamento mais forte e reutilização de código.

Os namespaces são namespacedefinidos usando palavras-chave e seu conteúdo pode ser acessado pelo nome do namespace.

Os módulos são moduledefinidos usando palavras-chave, que podem ser usadas para importimportar conteúdo de outros módulos.

Para novos projetos, recomenda-se o uso de módulos para organizar e gerenciar o código, o que proporciona melhor escalabilidade e recursos de gerenciamento de código.

2. Aplicação do TypeScript na prática

2.1 Verificação de tipo estático e detecção de erros em tempo de compilação

2.1.1 Como funciona o compilador TypeScript

Um compilador TypeScript é uma ferramenta que converte o código TypeScript em código JavaScript. Ele faz isso através das seguintes etapas:

  1. Análise Lexical : Divida o código-fonte em unidades lexicais individuais (tokens), como nomes de variáveis, palavras-chave, operadores, etc. O analisador léxico (Lexer) realiza a análise de acordo com as regras lexicais definidas pela especificação da linguagem.

  2. Análise de sintaxe : Combinando unidades lexicais em unidades gramaticais individuais, como expressões, declarações, funções, etc. O parser (Parser) analisa de acordo com as regras gramaticais definidas pela especificação da linguagem e constrói uma árvore de sintaxe abstrata (Abstract Syntax Tree, AST).

  3. Análise Semântica (Análise Semântica) : Inspeção semântica da árvore de sintaxe abstrata, incluindo a correção de declarações de variáveis, correspondência de tipo, etc. Os analisadores semânticos verificam se o código está em conformidade com o sistema de tipos e as especificações de sintaxe do TypeScript.

  4. Verificação de tipo (verificação de tipo) : executa a verificação de tipo com base em anotações de tipo de variáveis ​​e funções e inferência de contexto. O verificador de tipo verifica se os tipos em seu código são consistentes e fornece dicas de tipo e detecção de erro.

  5. Geração de código : de acordo com os resultados da análise semântica e verificação de tipo, gere o código JavaScript correspondente. O código gerado pode ser ES3, ES5, ES6 e outras versões diferentes de JavaScript.

2.1.2 Vantagens da verificação de tipo estático

A verificação estática de tipo é um recurso importante do TypeScript. Ela executa a verificação de tipo em tempo de compilação e tem as seguintes vantagens:

  1. Detecção antecipada de erros : A verificação estática de tipo pode detectar erros de tipo em tempo de compilação, evitando problemas de tipo oculto em tempo de execução. Isso reduz efetivamente o tempo gasto na depuração e solução de problemas e melhora a confiabilidade do código.

  2. Melhor capacidade de manutenção do código : por meio de anotações de tipo e verificação de tipo, melhores recursos de autodocumentação do código podem ser fornecidos, tornando o código mais fácil de entender e manter. As fortes restrições de tipo também podem reduzir a conversão desnecessária de tipos e o tratamento de exceções.

  3. Suporte de ferramenta de desenvolvimento inteligente : informações de tipo estático podem fornecer informações de contexto ricas para ferramentas de desenvolvimento (como editores de código e IDEs), incluindo funções como preenchimento automático de código, derivação de tipo e navegação de código, melhorando a eficiência do desenvolvimento e a qualidade do código.

  4. Melhor colaboração da equipe : a verificação de tipo estático pode padronizar o estilo de escrita do código e a definição da interface, ajudar os membros da equipe a seguir especificações unificadas, reduzir os custos de comunicação e melhorar a eficiência da colaboração.

Embora a verificação de tipo estático acrescente algum custo de desenvolvimento, ela pode fornecer um código mais seguro e confiável, reduzindo possíveis erros e problemas. Portanto, a verificação estática de tipo é uma ferramenta muito valiosa em grandes projetos e desenvolvimento de equipes.

2.2 Escrever código sustentável

2.2.1 Anotações de tipo e legibilidade do código

No TypeScript, as anotações de tipo podem ser usadas para adicionar informações de tipo a variáveis, parâmetros de função e valores de retorno de função. As anotações de tipo podem não apenas fornecer ao compilador verificação de tipo, mas também melhorar a legibilidade e a capacidade de manutenção do código.

legibilidade do código

As anotações de tipo podem tornar o código mais fácil de entender e ler. Por meio de anotações de tipo, os leitores podem entender claramente o tipo esperado de variáveis, evitando adivinhações sobre o contexto.

// 未使用类型注解
function calculateArea(radius) {
    
    
  return Math.PI * radius * radius;
}

// 使用类型注解
function calculateArea(radius: number): number {
    
    
  return Math.PI * radius * radius;
}

No exemplo acima, a segunda função usa anotações de tipo, que indicam claramente radiusos tipos de parâmetros e valores de retorno da função, tornando o código mais legível.

manutenibilidade do código

As anotações de tipo também podem melhorar a capacidade de manutenção do código. As informações de tipo podem ser fornecidas para ferramentas de desenvolvimento, como editores de código e IDEs, para fornecer melhor conclusão de código, verificação de tipo e notificação de erro. Isso ajuda os desenvolvedores a entender e modificar o código com mais facilidade e reduz a chance de erros.

// 使用类型注解
function calculateArea(radius: number): number {
    
    
  return Math.PI * radius * radius;
}

calculateArea(5); // 编辑器会提示参数类型错误,应为提供了类型注解

calculateArea("5"); // 编辑器会提示参数类型错误,应为提供了类型注解

No exemplo acima, se calculateAreao tipo de parâmetro incorreto for fornecido ao chamar a função, o editor exibirá um erro imediatamente para ajudar os desenvolvedores a encontrar e corrigir o problema.

2.2.2 Refatoração de código e suporte IDE

A verificação de tipo estático do TypeScript e o suporte a IDE fornecem grande conveniência para refatoração de código. O IDE pode fornecer ferramentas inteligentes de refatoração com base na semântica e informações de tipo do código para ajudar os desenvolvedores a refatorar e otimizar o código.

Operações comuns de refatoração de código incluem extração de função, renomeação de variável, conversão de tipo, etc. O IDE pode fornecer funções como renomeação automática, extração de funções, extração de constantes, etc., para evitar a modificação manual de um grande número de códigos repetitivos.

Por exemplo, ao renomear uma variável, o IDE pode atualizar automaticamente todo o código que faz referência à variável para garantir modificações consistentes:

// 重命名前
let age = 25;
console.log(age);

// 重命名后
let userAge = 25;
console.log(userAge);

O IDE também pode fornecer inspeção de código e prompts de erro para ajudar os desenvolvedores a encontrar possíveis problemas durante o processo de refatoração e fornecer sugestões de reparo.

Aproveitando a verificação de tipo estático do TypeScript e o forte suporte do IDE, os desenvolvedores podem refatorar seu código com mais facilidade, melhorando a capacidade de manutenção e legibilidade do código.

2.3 Usando frameworks e ferramentas TypeScript

2.3.1 Suporte TypeScript para estrutura Angular

Angular é uma estrutura front-end baseada em TypeScript que fornece suporte completo a TypeScript. O uso do TypeScript pode aumentar a capacidade de manutenção e a legibilidade do código e fornecer recursos como verificação de tipo estático e dicas de código inteligentes.

No Angular, você pode usar TypeScript para definir componentes, serviços, diretivas, etc. Usando anotações de tipo e interfaces para esclarecer os tipos de dados, você pode reduzir erros e fornecer uma melhor experiência de desenvolvimento.

Aqui está um exemplo de um componente Angular escrito em TypeScript:

import {
    
     Component } from '@angular/core';

@Component({
    
    
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {
    
    
  name: string = 'John Doe';
  age: number = 25;

  constructor() {
    
    
    this.greet();
  }

  greet(): void {
    
    
    console.log(`Hello, ${
      
      this.name}!`);
  }
}

No exemplo acima, definimos um MyComponentcomponente Angular chamado Angular usando TypeScript. Ao usar anotações de tipo, especificamos que nameo tipo do atributo é string, e ageo tipo do atributo é number. Também definimos um greetmétodo que é chamado quando o componente é inicializado e imprime a saudação no console.

2.3.2 Desenvolvimento React com TypeScript

React é outra estrutura de front-end comumente usada que também tem boa compatibilidade com TypeScript. O uso do TypeScript fornece suporte para verificação de tipo mais poderosa e ferramentas de desenvolvimento para aplicativos React.

Ao usar TypeScript para desenvolvimento React, você pode usar anotações de tipo para definir os tipos de componentes Props e State, bem como o tipo de retorno de componentes de função. Isso garante a exatidão dos dados, reduzindo erros e tempo de depuração.

Aqui está um exemplo de um componente React simples escrito em TypeScript:

import React, {
    
     useState } from 'react';

interface CounterProps {
    
    
  initialValue: number;
}

const Counter: React.FC<CounterProps> = ({
    
     initialValue }) => {
    
    
  const [count, setCount] = useState(initialValue);

  const increment = () => {
    
    
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>Count: {
    
    count}</p>
      <button onClick={
    
    increment}>Increment</button>
    </div>
  );
};

export default Counter;

No exemplo acima, definimos um Countercomponente de função React chamado . Ao usar uma interface CounterProps, especificamos initialValueo tipo de propriedade de um componente. Use useStateganchos para gerenciar o estado do componente e funções de seta para definir incrementfunções que incrementam o contador.

2.3.3 Escrevendo casos de teste e arquivos de declaração de tipo

O uso do TypeScript pode escrever casos de teste mais precisos (Casos de teste) para aumentar a confiabilidade do código. Escrever código de teste de tipo seguro pode impedir a passagem incorreta de tipos de dados e outros problemas potenciais.

Além disso, ao usar o TypeScript para desenvolver bibliotecas ou estruturas, escrever arquivos de declaração de tipo (arquivos de declaração de tipo) também é uma etapa importante. Os arquivos de declaração de tipo fornecem informações de tipo para bibliotecas ou estruturas JavaScript, permitindo os benefícios da verificação de tipo e dicas de código ao usar essas bibliotecas em projetos TypeScript.

Por exemplo, ao usar o TypeScript para desenvolver uma biblioteca integrada a uma biblioteca externa, você pode escrever um arquivo de declaração de tipo correspondente para descrever os tipos e interfaces da biblioteca. Isso fornece uma melhor experiência de desenvolvimento para desenvolvedores que usam a biblioteca.

Em suma, o uso de TypeScript para desenvolvimento de estrutura e ferramenta pode fornecer melhor verificação de tipo, dicas de código e experiência de desenvolvimento. Ele aumenta a capacidade de manutenção e legibilidade do código e reduz possíveis erros. Ao mesmo tempo, escrever casos de teste precisos e arquivos de declaração de tipo também é um aspecto importante do desenvolvimento com TypeScript.

3. Melhores práticas e técnicas

3.1 Compilação e manutenção de arquivos de declaração de tipo

Arquivos de declaração de tipo (Arquivos de declaração de tipo) são arquivos usados ​​para descrever as informações de tipo de uma biblioteca ou módulo JavaScript. Escrever e manter bons arquivos de declaração de tipo pode fornecer uma melhor verificação de tipo e dicas de código para projetos TypeScript.

Aqui estão algumas práticas recomendadas e dicas para escrever e manter arquivos de declaração de tipo:

  1. Instale @typeso pacote: Muitas bibliotecas JavaScript já possuem arquivos de declaração de tipo correspondentes disponíveis e geralmente são @typesnomeados com o prefixo . Ao instalar uma biblioteca de terceiros, você pode verificar se existe um arquivo de declaração de tipo correspondente e, em caso afirmativo, pode instalar diretamente o arquivo de declaração de tipo, por exemplo: npm install @types/library-name.

  2. Crie um arquivo de declaração de tipo personalizado: Se você não conseguir localizar um arquivo de declaração de tipo para uma biblioteca ou se quiser modificar um arquivo de declaração de tipo existente para atender às suas necessidades específicas, poderá criar manualmente um arquivo de declaração de tipo personalizado. Em geral, a convenção de nomenclatura para arquivos de declaração de tipo personalizado é library-name.d.ts, por exemplo my-library.d.ts, .

  3. Use declarações globais: ao chamar objetos ou variáveis ​​globais, você pode usar declarações globais para informar ao TypeScript o tipo desses objetos ou variáveis. declareVariáveis ​​globais, funções e namespaces podem ser definidos usando a palavra-chave em um arquivo de declaração global .

  4. Manter o tipo: À medida que a versão da biblioteca JavaScript muda, o arquivo de declaração de tipo também precisa ser atualizado e mantido de acordo. Às vezes, a API de uma biblioteca pode mudar ou pode haver bugs que precisam ser corrigidos. Ao usar bibliotecas de terceiros, é importante ficar de olho nas atualizações da biblioteca e nas versões publicadas do arquivo de declaração de tipo.

  5. Arquivo de declaração de tipo de teste: Ao escrever ou modificar um arquivo de declaração de tipo, você pode escrever casos de teste correspondentes para verificar se o tipo está correto. Você pode criar um diretório de teste especial, escrever .test-d.tsum arquivo de declaração de tipo de teste terminando com e usar ferramentas de teste para verificação de tipo.

  6. Use ferramentas para auxiliar na redação: Use ferramentas como dts-gen, tsdou plug-ins de editor para auxiliar na geração do arquivo de declaração de tipo inicial, melhorando a eficiência e a precisão da redação.

3.2 Use genéricos para melhorar a reutilização de código

Os genéricos são um recurso poderoso do TypeScript que permite usar tipos de maneira parametrizada em funções, classes e interfaces. O uso de genéricos pode melhorar a reutilização e a flexibilidade do código, tornando o código mais versátil e extensível.

Aqui estão algumas práticas recomendadas e dicas para usar genéricos para aumentar a reutilização de código:

  1. Genéricos de função: Ao definir uma função, você pode usar genéricos para especificar os tipos de parâmetro ou tipos de valor de retorno da função. Dessa forma, a função pode ser aplicada a diferentes tipos de entrada e não requer declaração de tipo quando chamada.
function identity<T>(value: T): T {
    
    
  return value;
}

let result = identity<string>("Hello");
  1. Genéricos de classe: as classes podem usar genéricos para definir os tipos de propriedades, métodos e construtores da classe. Isso torna possível criar classes reutilizáveis ​​e especificar tipos concretos ao instanciá-los.
class Container<T> {
    
    
  private value: T;
  
  constructor(value: T) {
    
    
    this.value = value;
  }
  
  getValue(): T {
    
    
    return this.value;
  }
}

let container = new Container<number>(42);
let value = container.getValue();
  1. Genéricos de interface: as interfaces também podem usar genéricos para especificar o tipo no momento da implementação. Isso permite que você crie interfaces genéricas e especifique tipos concretos ao implementá-las.
interface List<T> {
    
    
  add(item: T): void;
  get(index: number): T;
}

class ArrayList<T> implements List<T> {
    
    
  private items: T[] = [];

  add(item: T): void {
    
    
    this.items.push(item);
  }

  get(index: number): T {
    
    
    return this.items[index];
  }
}

let list = new ArrayList<number>();
list.add(1);
list.add(2);
let value = list.get(1); // value 的类型为 number
  1. Restrições genéricas: Às vezes, os genéricos precisam ser restritos para limitar os tipos que podem ser usados. Você pode usar extendsa palavra-chave para restringir o escopo de tipo de um genérico.
interface Lengthwise {
    
    
  length: number;
}

function getLength<T extends Lengthwise>(obj: T): number {
    
    
  return obj.length;
}

let result = getLength("Hello"); // result 的类型为 number,因为字符串有 length 属性
  1. Vários parâmetros genéricos: vários parâmetros genéricos podem ser usados ​​simultaneamente em uma função, classe ou interface para lidar com vários tipos de dados.
function pair<T, U>(value1: T, value2: U): [T, U] {
    
    
  return [value1, value2];
}

let result = pair<string, number>("Hello", 42); // result 的类型为 [string, number]

O uso de genéricos pode aumentar a flexibilidade e a capacidade de reutilização de seu código, tornando-o mais genérico e seguro para tipos.

3.3 Declaração de bibliotecas JavaScript estendidas e módulos de terceiros

Ao usar bibliotecas JavaScript ou módulos de terceiros, eles podem ser estendidos com arquivos de declaração de tipo para melhor verificação de tipo e dicas de código.

Aqui estão algumas práticas recomendadas e dicas para estender bibliotecas JavaScript e declarações de módulos de terceiros:

  1. Aquisição e instalação do arquivo de declaração: primeiro verifique se há um arquivo de declaração de tipo correspondente disponível e você pode usar o @typespacote de prefixo para instalá-lo. Se não houver nenhum arquivo de declaração de tipo correspondente, você pode tentar procurar por arquivos de declaração de tipo mantidos pela comunidade.

  2. Escreva um arquivo de declaração personalizado: Se você não conseguir encontrar um arquivo de declaração de tipo adequado, poderá escrever manualmente um arquivo de declaração personalizado. Você pode criar um .d.tsarquivo terminando em e escrever nele as declarações de tipo para a biblioteca ou módulo correspondente.

  3. Usando declarea palavra-chave: Em um arquivo de declaração de tipo, você pode usar declarea palavra-chave para informar ao TypeScript sobre informações de tipo sobre uma biblioteca ou módulo. Você pode declarar variáveis ​​globais, funções, classes, interfaces, etc.

  4. Envie um arquivo de declaração mantido pela comunidade: Se você escrever um arquivo de declaração geral, poderá contribuir com ele para um repositório de declaração de tipo mantido pela comunidade, como odefinitivamenteTyped. Isso beneficia outros desenvolvedores e ajuda a melhorar a qualidade do ecossistema como um todo.

  5. Atualização e manutenção: À medida que a versão da biblioteca ou do módulo muda, o arquivo de declaração de tipo também precisa ser atualizado e mantido de acordo. Preste atenção à atualização da biblioteca no tempo e mantenha-se sincronizado com a comunidade para garantir a precisão e integridade do arquivo de declaração de tipo.

Ao usar bibliotecas JavaScript ou módulos de terceiros, estendendo seus arquivos de declaração de tipo, você pode obter uma melhor verificação de tipo, dica de código e experiência de desenvolvimento. Isso é inestimável para criar e manter projetos TypeScript.

Quatro. Resumo

Por meio da introdução deste artigo, aprendemos sobre a importante função e a prática de aplicação do TypeScript no desenvolvimento de front-end. O TypeScript fornece tipos de dados avançados, interfaces e definições de função para nos ajudar a escrever código com mais precisão e melhorar a qualidade e a legibilidade do código por meio da verificação de tipo. Ele se integra perfeitamente com o código JavaScript existente e tem compatibilidade entre navegadores e plataformas cruzadas. Usando o TypeScript, podemos organizar, manter e estender melhor o código durante o processo de desenvolvimento, melhorando a eficiência do desenvolvimento e a colaboração da equipe. Portanto, seja desenvolvimento pessoal ou trabalho em equipe, o TypeScript é uma ferramenta importante que vale a pena explorar e aplicar.

Acho que você gosta

Origin blog.csdn.net/weixin_55756734/article/details/131947820
Recomendado
Clasificación