Tabemos as principais características do TypeScript Type System quando discutimos Por que TypeScript? A seguir estão alguns pontos chave dessa discussão que não precisam de mais explicações:

  • O sistema de tipo em TypeScript foi projetado para ser opcional para que o seu JavaScript seja TypeScript.

  • O TypeScript não bloqueia a emissão de JavaScript na presença de erros de tipo, permitindo-lhe actualizar progressivamente o seu JS para TS.

Agora vamos começar com a sintaxe do sistema de tipo TypeScript. Desta forma você pode começar a usar estas anotações no seu código imediatamente e ver o benefício. Isto irá prepará-lo para um mergulho mais profundo mais tarde.

Como mencionado antes Tipos são anotados usando a sintaxe :TypeAnnotation. Qualquer coisa que esteja disponível no espaço de declaração de tipo pode ser usada como uma Anotação de Tipo.

O exemplo seguinte demonstra anotações de tipo para variáveis, parâmetros de função e valores de retorno de função:

var num: number = 123;
function identity(num: number): number {
return num;
}

Tipos Primitivos

Os tipos primitivos JavaScript estão bem representados no sistema de tipo TypeScript. Isto significa string, number, boolean como demonstrado abaixo:

var num: number;
var str: string;
var bool: boolean;
num = 123;
num = 123.456;
num = '123'; // Error
str = '123';
str = 123; // Error
bool = true;
bool = false;
bool = 'false'; // Error

Arrays

TypeScript fornece sintaxe de tipo dedicada para arrays para facilitar a anotação e documentação do seu código. A sintaxe é basicamente a pós-fixação a qualquer anotação de tipo válida (por exemplo, :boolean). Ela permite que você faça com segurança qualquer manipulação de array que você normalmente faria e o protege de erros como a atribuição de um membro do tipo errado. Isto é demonstrado abaixo:

var boolArray: boolean;
boolArray = ;
console.log(boolArray); // true
console.log(boolArray.length); // 2
boolArray = true;
boolArray = ;
boolArray = 'false'; // Error!
boolArray = 'false'; // Error!
boolArray = ; // Error!

Interfaces

Interfaces são a forma principal no TypeScript para compor múltiplas anotações de tipo em uma única anotação nomeada. Considere o seguinte exemplo:

interface Name {
first: string;
second: string;
}
var name: Name;
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Aqui compusemos as anotações first: string + second: string em uma nova anotação Name que reforça as verificações de tipo em membros individuais. As interfaces têm muito poder no TypeScript e nós vamos dedicar uma seção inteira a como você pode usar isso em seu benefício.

Anotação Tipo Inline

Em vez de criar uma nova interface você pode anotar o que quiser na linha usando :{ /*Structure*/ }. O exemplo anterior apresentado novamente com um tipo inline:

var name: {
first: string;
second: string;
};
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Os tipos inline são ótimos para fornecer rapidamente uma anotação de um tipo inline para algo. Isso poupa-lhe o incómodo de encontrar um nome de tipo (potencialmente mau). Entretanto, se você se encontrar colocando o mesmo tipo de anotação em linha várias vezes, é uma boa idéia considerar refatorá-la em uma interface (ou um type alias coberto mais tarde nesta seção).

Tipos Especiais

Além dos tipos primitivos que foram cobertos há alguns tipos que têm um significado especial no TypeScript. Estes são any, null, undefined, void.

qualquer

O tipo any ocupa um lugar especial no sistema de tipo TypeScript. Ele lhe dá uma escotilha de escape do sistema de tipo para avisar o compilador para se desligar. any é compatível com qualquer e todos os tipos no sistema de tipo. Isto significa que qualquer coisa pode ser atribuída a ele e pode ser atribuída a qualquer coisa. Isto é demonstrado no exemplo abaixo:

var power: any;
// Takes any and all types
power = '123';
power = 123;
// Is compatible with all types
var num: number;
power = num;
num = power;

Se você está portando código JavaScript para TypeScript, você vai ser amigo íntimo de any no início. No entanto, não leve essa amizade muito a sério, pois isso significa que cabe a você garantir a segurança do tipo. Você está basicamente a dizer ao compilador para não fazer nenhuma análise estática significativa.

nulo e indefinido

Como eles são tratados pelo sistema de tipo depende da bandeira strictNullChecks do compilador (nós cobrimos esta bandeira mais tarde). Quando em strictNullCheck:false, os caracteres null e undefined JavaScript são efetivamente tratados pelo sistema de tipo o mesmo que algo do tipo any. Estes literais podem ser atribuídos a qualquer outro tipo. Isto é demonstrado no exemplo abaixo:

var num: number;
var str: string;
// These literals can be assigned to anything
num = null;
str = undefined;

:void

Utilizar :void para significar que uma função não tem um tipo de retorno:

function log(message): void {
console.log(message);
}

Generics

Muitos algoritmos e estruturas de dados em informática não dependem do tipo real do objeto. No entanto, o usuário ainda deseja impor uma restrição entre várias variáveis. Um exemplo simples de brinquedo é uma função que pega uma lista de itens e retorna uma lista invertida de itens. A restrição aqui é entre o que é passado para a função e o que é retornado pela função:

function reverse<T>(items: T): T {
var toreturn = ;
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items);
}
return toreturn;
}
var sample = ;
var reversed = reverse(sample);
console.log(reversed); // 3,2,1
// Safety!
reversed = '1'; // Error!
reversed = ; // Error!
reversed = 1; // Okay
reversed = ; // Okay

Aqui você está basicamente dizendo que a função reverse toma um array (items: T) de algum tipo T (observe o parâmetro de tipo em reverse<T>) e retorna um array de tipo T (observe : T). Como a função reverse devolve itens do mesmo tipo, TypeScript sabe que a variável reversed também é do tipo number e lhe dará segurança ao Type. Similarmente se você passar em um array de string para a função reversa o resultado retornado também é um array de string e você obtém segurança do tipo similar como mostrado abaixo:

var strArr = ;
var reversedStrs = reverse(strArr);
reversedStrs = ; // Error!

De fato, arrays JavaScript já têm uma função .reverse e TypeScript de fato usa genéricos para definir sua estrutura:

interface Array<T> {
reverse(): T;
// ...
}

Isto significa que você obtém segurança de digitação ao chamar .reverse em qualquer array como mostrado abaixo:

var numArr = ;
var reversedNums = numArr.reverse();
reversedNums = ; // Error!

Discutiremos mais tarde sobre a interface Array<T> quando apresentarmos lib.d.ts na seção Declarações Ambientais.

Tipo de União

Bastante comumente em JavaScript você quer permitir que uma propriedade seja de múltiplos tipos, por exemplo, um string ou um number. É aqui que o tipo de união (indicado por | numa anotação de tipo, por exemplo, string|number) vem a calhar. Um caso de uso comum é uma função que pode pegar um único objeto ou um array do objeto e.g.:

function formatCommandline(command: string|string) {
var line = '';
if (typeof command === 'string') {
line = command.trim();
} else {
line = command.join(' ').trim();
}
// Do stuff with line: string
}

Tipo de Intersecção

extend é um padrão muito comum em JavaScript onde você pega dois objetos e cria um novo que tem as características de ambos os objetos. Um Tipo de Intersecção permite-lhe usar este padrão de uma forma segura como demonstrado abaixo:

function extend<T, U>(first: T, second: U): T & U {
return { ...first, ...second };
}
const x = extend({ a: "hello" }, { b: 42 });
// x now has both `a` and `b`
const a = x.a;
const b = x.b;

Tuple Type

JavaScript não tem suporte de tuple de primeira classe. As pessoas geralmente usam apenas um array como um tuple. Isto é exatamente o que o sistema tipo TypeScript suporta. Tuples pode ser anotado usando : etc. Um tuple pode ter qualquer número de membros. Tuples são demonstrados no exemplo abaixo:

var nameNumber: ;
// Okay
nameNumber = ;
// Error!
nameNumber = ;

Combine isto com o suporte a desestruturação em TypeScript, tuples sentem-se razoavelmente de primeira classe apesar de serem arrays por baixo:

var nameNumber: ;
nameNumber = ;
var = nameNumber;

Type Alias

TypeScript fornece uma sintaxe conveniente para fornecer nomes para anotações de tipo que você gostaria de usar em mais de um lugar. Os alias são criados usando a sintaxe type SomeName = someValidTypeAnnotation. Um exemplo é demonstrado abaixo:

type StrOrNum = string|number;
// Usage: just like any other notation
var sample: StrOrNum;
sample = 123;
sample = '123';
// Just checking
sample = true; // Error!

Unlike an interface você pode dar um alias de tipo para literalmente qualquer tipo de anotação (útil para coisas como tipos de união e intersecção). Aqui estão mais alguns exemplos para familiarizá-lo com a sintaxe:

type Text = string | { text: string };
type Coordinates = ;
type Callback = (data: string) => void;

TIP: Se você precisa ter hierarquias de anotações de tipo use um interface. Elas podem ser usadas com implements e extends

TIP: Use um tipo alias para estruturas de objetos mais simples (como Coordinates) apenas para dar-lhes um nome semântico. Também quando você quer dar nomes semânticos aos tipos Union ou Intersection, um alias Type é o caminho a seguir.

Summary

Agora que você pode começar a anotar a maior parte do seu código JavaScript, podemos saltar para os detalhes de toda a potência disponível no TypeScript’s Type System.

Deixe uma resposta

O seu endereço de email não será publicado.