0

Typescript para Programadores

#TypeScript
A
Alfredo Neto

TypeScript para programadores JavaScript

O TypeScript mantém uma relação incomum com o JavaScript. O TypeScript oferece todos os recursos do JavaScript e uma camada adicional sobre eles: o sistema de tipos do TypeScript.

Por exemplo, JavaScript fornece primitivos de linguagem como stringnumberobject, mas não verifica se você os atribuiu consistentemente. TypeScript sim.

Isso significa que seu código JavaScript de trabalho existente também é código TypeScript. O principal benefício do TypeScript é que ele pode destacar um comportamento inesperado em seu código, reduzindo a chance de bugs.

Este tutorial fornece uma breve visão geral do TypeScript, enfocando seu sistema de tipos.



Tipos por inferência

TypeScript conhece a linguagem JavaScript e irá gerar tipos para você em muitos casos. Por exemplo, ao criar uma variável e atribuí-la a um valor específico, o TypeScript usará o valor como seu tipo.

let helloWorld = "Hello World";
//  ^ = let helloWorld: string
Tentar

Ao compreender como o JavaScript funciona, o TypeScript pode construir um sistema de tipos que aceita código JavaScript, mas possui tipos. Isso oferece um sistema de tipos sem a necessidade de adicionar caracteres extras para tornar os tipos explícitos em seu código. É assim que o TypeScript sabe que helloWorldé um stringno exemplo acima.

Você pode ter escrito JavaScript no Visual Studio Code e ter preenchimento automático do editor. O Visual Studio Code usa o TypeScript nos bastidores para facilitar o trabalho com JavaScript.



Definindo Tipos

Você pode usar uma grande variedade de padrões de design em JavaScript. No entanto, alguns padrões de projeto dificultam a inferência automática de tipos (por exemplo, padrões que usam programação dinâmica). Para cobrir esses casos, o TypeScript oferece suporte a uma extensão da linguagem JavaScript, que oferece locais para você dizer ao TypeScript quais devem ser os tipos.

Por exemplo, para criar um objeto com um tipo inferido que inclui name: stringid: number, você pode escrever:

const user = {
  name: "Hayes",
  id: 0,
};
Tentar

Você pode descrever explicitamente a forma deste objeto usando uma interfacedeclaração:

interface User {
  name: string;
  id: number;
}
Tentar

Em seguida, você pode declarar que um objeto JavaScript está em conformidade com a forma do seu novo interfaceusando uma sintaxe como a de : TypeNameuma declaração de variável:

const user: User = {
  name: "Hayes",
  id: 0,
};
Tentar

Se você fornecer um objeto que não corresponda à interface fornecida, o TypeScript o avisará:

interface User {
  name: string;
  id: number;
}


const user: User = {
  username: "Hayes",
Type '{ username: string; id: number; }' is not assignable to type 'User'.
  Object literal may only specify known properties, and 'username' does not exist in type 'User'.
Type '{ username: string; id: number; }' is not assignable to type 'User'.
  Object literal may only specify known properties, and 'username' does not exist in type 'User'.
  id: 0,
};
Tentar

Como o JavaScript oferece suporte a classes e programação orientada a objetos, o TypeScript também. Você pode usar uma declaração de interface com classes:

interface User {
  name: string;
  id: number;
}


class UserAccount {
  name: string;
  id: number;


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


const user: User = new UserAccount("Murphy", 1);
Tentar

Você pode usar interfaces para anotar parâmetros e retornar valores para funções:

function getAdminUser(): User {
  //...
}


function deleteUser(user: User) {
  // ...
}
Tentar

Já há um pequeno conjunto de tipos primitivos disponíveis em JavaScript: booleanbigintnullnumberstringsymbolobject, e undefined, que você pode usar em uma interface. O TypeScript estende esta lista com mais alguns, como any(permitir qualquer coisa), unknown(garantir que alguém usando este tipo declare qual é o tipo), never(não é possível que esse tipo aconteça) e void(uma função que retorna undefinedou não tem retorno valor).

Você verá que existem duas sintaxes para construir tipos: Interfaces e Tipos . Você deve preferir interface. Use typequando precisar de recursos específicos.



Tipos de composição

Com o TypeScript, você pode criar tipos complexos combinando tipos simples. Existem duas maneiras populares de fazer isso: com sindicatos e com genéricos.



Sindicatos

Com uma união, você pode declarar que um tipo pode ser um de vários tipos. Por exemplo, você pode descrever um booleantipo como sendo trueou false:

type MyBool = true | false;
Tentar

Observação: se você passar o mouse MyBoolacima, verá que está classificado como boolean. Essa é uma propriedade do Sistema de Tipo Estrutural. Mais sobre isso abaixo.

Um caso de uso popular para tipos de união é descrever o conjunto de literais s stringou numbers que um valor pode ser:

type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type OddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;
Tentar

Os sindicatos também fornecem uma maneira de lidar com diferentes tipos. Por exemplo, você pode ter uma função que leva um arrayou um string:

function getLength(obj: string | string[]) {
  return obj.length;
}
Tentar

Para aprender o tipo de uma variável, use typeof:

ModeloPredicadofragmentotypeof s === "string"númerotypeof n === "number"boleanotypeof b === "boolean"Indefinidotypeof undefined === "undefined"funçãotypeof f === "function"variedadeArray.isArray(a)

Por exemplo, você pode fazer com que uma função retorne valores diferentes, dependendo se é passada uma string ou uma matriz:

function wrapInArray(obj: string | string[]) {
  if (typeof obj === "string") {
    return [obj];
//          ^ = (parameter) obj: string
  } else {
    return obj;
  }
}
Tentar


Genéricos

Os genéricos fornecem variáveis ​​para tipos. Um exemplo comum é um array. Uma matriz sem genéricos pode conter qualquer coisa. Uma matriz com genéricos pode descrever os valores que a matriz contém.

type StringArray = Array<string>;
type NumberArray = Array<number>;
type ObjectWithNameArray = Array<{ name: string }>;

Você pode declarar seus próprios tipos que usam genéricos:

interface Backpack<Type> {
  add: (obj: Type) => void;
  get: () => Type;
}


// This line is a shortcut to tell TypeScript there is a
// constant called `backpack`, and to not worry about where it came from.
declare const backpack: Backpack<string>;


// object is a string, because we declared it above as the variable part of Backpack.
const object = backpack.get();


// Since the backpack variable is a string, you can't pass a number to the add function.
backpack.add(23);
Argument of type 'number' is not assignable to parameter of type 'string'.
Argument of type 'number' is not assignable to parameter of type 'string'.
Tentar


Sistema de Tipo Estrutural

Um dos princípios básicos do TypeScript é que a verificação de tipo se concentra na forma que os valores têm. Isso às vezes é chamado de “tipagem de pato” ou “tipagem estrutural”.

Em um sistema de tipo estrutural, se dois objetos têm a mesma forma, eles são considerados do mesmo tipo.

interface Point {
  x: number;
  y: number;
}


function logPoint(p: Point) {
  console.log(`${p.x}, ${p.y}`);
}


// logs "12, 26"
const point = { x: 12, y: 26 };
logPoint(point);
Tentar

pointvariável nunca é declarada como um Pointtipo. No entanto, o TypeScript compara a forma de pointcom a forma de Pointna verificação de tipo. Eles têm a mesma forma, então o código é aprovado.

A correspondência de forma requer apenas um subconjunto dos campos do objeto para corresponder.

const point3 = { x: 12, y: 26, z: 89 };
logPoint(point3); // logs "12, 26"


const rect = { x: 33, y: 3, width: 30, height: 80 };
logPoint(rect); // logs "33, 3"


const color = { hex: "#187ABF" };
logPoint(color);
Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'.
  Type '{ hex: string; }' is missing the following properties from type 'Point': x, y
Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'.
  Type '{ hex: string; }' is missing the following properties from type 'Point': x, y
Tentar

Não há diferença entre como as classes e os objetos se conformam às formas:

class VirtualPoint {
  x: number;
  y: number;


  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}


const newVPoint = new VirtualPoint(13, 56);
logPoint(newVPoint); // logs "13, 56"
Tentar

Se o objeto ou classe tiver todas as propriedades necessárias, o TypeScript dirá que elas correspondem, independentemente dos detalhes de implementação.

0
18

Comentários (0)

alfredo gelk neto

Brasil