Linguagem da Microsoft, transpilada em JavaScript, atribuída de conceitos OOP como classes, módulos, interfaces, genéricos e (opcional) tipagem estática para JavaScript. Arquivos TypeScript possuem final '.ts'. Todo código JavaScript é TypeScript válido, podendo ser adicionado a qualquer projeto. Pode ser testado no playground online. Para transpirar arquivos TS para JS, utiliza-se comando "tsc arquivo.ts".
npm install -g typescript // Pré-requisito Node.js
tsc -v
console.log("Olá!"); // Imprimir no console
var isDone: boolean = false; // Booleano true ou false
var lines: number = 42; // Números inteiros ou decimais
var name: string = "Anders"; // String com aspas duplas ou simples
var notSure: any = 4; // Qualquer tipo
notSure = "maybe a string instead";
notSure = false;
var list: number[] = [1, 2, 3]; // Matriz
var list: Array<number> = [1, 2, 3]; // Matriz genérica
// Percorrer valores da matriz
for (var i = 0; i < list.length; i++) {
console.log(list[i]);
}
for (var i in list) {
console.log(list[i]);
}
for (var i of list) {
console.log(i);
}
var x: [string, number]; // Tupla
x = ["hello", 10]; // OK
x = [10, "hello"]; // Erro
enum Color {Red, Green, Blue}; // Enumeração
var c: Color = Color.Green; // 1
var colorName: string = Color[2]; // Blue
var notSure: unknown = 4; // Tipo desconhecido
var u: undefined = undefined; // Indefinido
var n: null = null; // Nulo
function bigHorribleAlert(): void { // Vazio (sem retorno)
alert("I'm a little annoying box!");
}
function soma(x: number, y: number): number {
return x + y;
}
console.log(soma(1, 2)); // 3
// Função com parâmetros opcionais
function buildName(firstName: string, lastName?: string): string {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
console.log(buildName("John")); // John
console.log(buildName("John", "Doe")); // John Doe
// Função anônima
var f1 = function (i: number): number { return i * i; }
console.log(f1(3)); // 9
// Tipo de retorno inferido
var f2 = function (i: number) { return i * i; }
console.log(f2(4)); // 16
var f3 = (i: number): number => { return i * i; }
console.log(f3(5)); // 25
// Tipo de retorno inferido
var f4 = (i: number) => { return i * i; }
console.log(f4(6)); // 36
// Tipo de retorno inferido, one-liner significa nenhuma palavra-chave retorno necessário
var f5 = (i: number) => i * i;
console.log(f5(2)); // 4
interface Pessoa {
nome: string;
idade: number;
sexo?: string; // Opcional
[propName: string]: any; // Propriedades dinâmicas
}
function printPessoa(pessoa: Pessoa) {
console.log(pessoa.nome);
console.log(pessoa.idade);
console.log(pessoa.sexo);
}
var p1 = {nome: "João", idade: 25};
printPessoa(p1);
// Interfaces como tipo de função
interface SearchFunc {
(source: string, subString: string): boolean;
}
var mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
return src.search(sub) != -1;
}
console.log(mySearch("abc", "a")); // true
console.log(mySearch("abc", "d")); // false
// Implementação de interface
interface Usuario {
id: number;
nome: string;
email: string;
}
// Objeto que implementa interface Usuario
const user: Usuario = {
id: 1,
nome: "Maria",
email: "maria@email.com"
};
console.log("Usuário:");
console.log(`ID: ${user.id}`);
console.log(`Nome: ${user.nome}`);
console.log(`Email: ${user.email}`);
// Objeto com propriedades dinâmicas
const obj: { [key: string]: string } = {
nome: "João",
idade: "25"
};
// Exibir dados do objeto com propriedades dinâmicas
console.log("\nObjeto com propriedades dinâmicas:");
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(`${key}: ${obj[key]}`);
}
}
// Objeto construído através de classe
class Pessoa {
nome: string;
idade: number;
constructor(nome: string, idade: number) {
this.nome = nome;
this.idade = idade;
}
printPessoa() {
console.log(this.nome);
console.log(this.idade);
}
}
var p1 = new Pessoa("João", 25);
p1.printPessoa();
var p: Pessoa = {nome: "João", idade: 25}; // Objeto que implementa interface Pessoa
var p: Person = { name: "Bobby", move: () => {} };
var validPerson: Person = { name: "Bobby", age: 42, move: () => {} }; // Propriedade opcional
var invalidPerson: Person = { name: "Bobby", age: true }; // Não é Person porque age não é número
class Animal {
nome: string;
constructor(nome: string, public idade: number = 0) {
this.nome = nome;
}
move(metros: number = 0) {
console.log(this.nome + " moveu " + metros + "m");
}
static origin = new Animal("Origem", 0);
}
var a = new Animal("Cachorro", 2);
a.move(10); // Cachorro moveu 10m
a.origin; // Origem moveu 0m
a.origin.move(0); // Origem moveu 0m
var b = new Animal("Gato");
console.log(b.idade); // idade é 0
class Cachorro extends Animal {
latir() {
console.log("Au au!");
}
}
var c = new Cachorro("Rex", 3);
c.move(10); // Rex moveu 10m
c.latir(); // Au au!
class Gato extends Animal {
constructor(nome: string, idade: number, public cor: string) {
super(nome, idade);
}
miar() {
console.log("Miau!");
}
}
var g = new Gato("Mingau", 1, "preto");
g.move(5); // Mingau moveu 5m
g.miar(); // Miau!
class Point {
x: number;
constructor(x: number, public y: number = 0) {
this.x = x;
}
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
static origin = new Point(0, 0);
}
var p1 = new Point(10 ,20);
var p2 = new Point(25);
// Herança
class Point3D extends Point {
constructor(x: number, y: number, public z: number = 0) {
super(x, y);
}
// Sobrescrever
dist() {
var d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
var p3 = new Point3D(10, 20, 30);
console.log(p3.dist()); // 37.416573867739416
console.log(Point.origin); // Point { x: 0, y: 0 }
console.log(Point3D.origin); // Point { x: 0, y: 0 }
console.log(Point3D.origin.dist()); // 0
console.log(Point3D.origin.z); // undefined
console.log(Point3D.origin.x); // 0
module Geometry {
export class Square {
constructor(public sideLength: number = 0) {
}
area() {
return Math.pow(this.sideLength, 2);
}
}
}
var s1 = new Geometry.Square(5); // 25 ("." pode ser utilizado como separador de sub módulos)
import G = Geometry; // Alias no local para fazer referência a um módulo
var s2 = new G.Square(10);
console.log(s2.area()); // 100
console.log(G.Square); // [Function: Square]
console.log(G.Square.prototype.area); // [Function: area]
console.log(G.Square.prototype.area()); // NaN
console.log(G.Square.prototype.area.call(s2)); // 100
console.log(G.Square.prototype.area.call(G.Square(5))); // NaN
// Export:
export interface StringValidator {
isAcceptable(s: string): boolean;
}
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5;
}
}
const validator = new ZipCodeValidator();
const testStrings = ["12345", "abcd", "678", "987654"];
testStrings.forEach((testString) => {
console.log(`"${testString}" é aceitável? ${validator.isAcceptable(testString)}`);
});
// Import:
import { ZipCodeValidator } from "./ZipCodeValidator";
let myValidator = new ZipCodeValidator();
let testStrings = ["12345", "9876", "ABCDE", "54321"];
testStrings.forEach((testString) => {
console.log(`"${testString}" é aceitável? ${myValidator.isAcceptable(testString)}`);
});
function retornaElemento<T>(elemento: T): T {
return elemento;
}
const numero = retornaElemento<number>(42);
const texto = retornaElemento<string>("Olá, TypeScript!");
console.log(numero); // 42
console.log(texto); // Olá, TypeScript!
console.log(retornaElemento<boolean>(true)); // true
// Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {
}
}
var t = new Tuple<number, string>(1, "Hello");
console.log(t.item1); // 1
console.log(t.item2); // Hello
console.log(t); // Tuple { item1: 1, item2: 'Hello' }
// Interfaces
interface Pair<T> {
item1: T;
item2: T;
}
console.log({ item1: 1, item2: 2 } as Pair<number>); // { item1: 1, item2: 2 }
console.log({ item1: "Hello", item2: "World" } as Pair<string>); // { item1: 'Hello', item2: 'World' }
// Funções
var pairToTuple = function<T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
var tuple = pairToTuple({ item1:"hello", item2:"world"});
console.log(tuple); // Tuple { item1: 'hello', item2: 'world' }
function imprimirId(id: number | string): void {
console.log(`ID: ${id}`);
}
imprimirId(123);
imprimirId("abc123");
interface A {
a: number;
}
interface B {
b: number;
}
type AB = A & B;
function imprimirAB(ab: AB): void {
console.log(`A: ${ab.a}, B: ${ab.b}`);
}
imprimirAB({ a: 1, b: 2 }); // A: 1, B: 2
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let strLength2: number = (someValue as string).length;
console.log(`Valor de someValue: "${someValue}"`);
console.log(`Comprimento da string (usando <string>): ${strLength}`);
console.log(`Comprimento da string (usando as string): ${strLength2}`);
type Direction = "left" | "right" | "up" | "down";
function move(direction: Direction): void {
console.log(`Moving ${direction}`);
}
move("left"); // Moving left
move("right"); // Moving right
move("up"); // Moving up
move("down"); // Moving down
type ID = number | string;
let meuId: ID = 123;
meuId = "abc";
// Partial:
interface User {
id: number;
name: string;
age: number;
}
let partialUser: Partial<User> = {
name: "Alice",
};
console.log("Objeto parcial de User:");
console.log(`Nome: ${partialUser.name}`);
console.log(`ID: ${partialUser.id ?? "não definido"}`);
console.log(`Idade: ${partialUser.age ?? "não definida"}`);
// Readonly:
interface User {
id: number;
name: string;
age: number;
}
let readonlyUser: Readonly<User> = {
id: 1,
name: "Bob",
age: 25,
};
// readonlyUser.age = 26; // Error: cannot reassign a readonly property
console.log("Objeto Readonly<User>:");
console.log(`ID: ${readonlyUser.id}`);
console.log(`Nome: ${readonlyUser.name}`);
console.log(`Idade: ${readonlyUser.age}`);
// Pick:
interface User {
id: number;
name: string;
age: number;
}
type UserName = Pick<User, "name">;
let userName: UserName = {
name: "Charlie",
};
console.log("Objeto UserName:");
console.log(`Nome: ${userName.name}`);
// Omit:
interface User {
id: number;
name: string;
age: number;
}
type UserWithoutAge = Omit<User, "age">;
let userWithoutAge: UserWithoutAge = {
id: 2,
name: "Dave",
};
console.log("Objeto UserWithoutAge:");
console.log(`ID: ${userWithoutAge.id}`);
console.log(`Nome: ${userWithoutAge.name}`);
enum Cor {
Vermelho = "Red",
Azul = "Blue",
Verde = "Green",
}
const minhaCor: Cor = Cor.Vermelho;
console.log(minhaCor); // Output: "Red"
// Class Decorator:
function sealed(constructor: Function) {
console.log("Sealing constructor:", constructor.name);
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
console.log("Greeter constructor called with message:", message);
}
greet() {
return "Hello, " + this.greeting;
}
}
console.log("Greeter class:", Greeter);
const greeterInstance = new Greeter("world");
console.log("Greeter instance:", greeterInstance);
console.log("Greet method output:", greeterInstance.greet());
// Method Decorator:
function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(`Setting enumerable to ${value} for method: ${propertyKey}`);
descriptor.enumerable = value;
};
}
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
console.log("Greeter constructor called with message:", message);
}
@enumerable(false)
greet() {
return "Hello, " + this.greeting;
}
}
console.log("Greeter prototype:", Object.getPrototypeOf(Greeter));
const greeterInstance = new Greeter("world");
console.log("Greeter instance:", greeterInstance);
console.log("Greet method output:", greeterInstance.greet());
console.log(
"Is greet enumerable?",
Object.prototype.propertyIsEnumerable.call(greeterInstance, "greet")
);
console.log("Enumerable properties of Greeter instance:", Object.keys(greeterInstance));
console.log(
"All properties of Greeter prototype:",
Object.getOwnPropertyNames(Object.getPrototypeOf(greeterInstance))
);
// Async/Await Decorator:
async function fetchData(url: string) {
console.log("Fetching data from URL:", url);
let response = await fetch(url);
console.log("Response status:", response.status);
let data = await response.json();
console.log("Data received:", data);
return data;
}
const testFetchData = async () => {
try {
const url = "https://jsonplaceholder.typicode.com/todos/1";
console.log("Starting fetchData test...");
const result = await fetchData(url);
console.log("Final result from fetchData:", result);
} catch (error) {
console.error("Error during fetchData:", error);
}
};
testFetchData();
namespace Geometry {
export interface Vector2D {
x: number;
y: number;
}
export interface Vector3D {
x: number;
y: number;
z: number;
}
}
const vector2D: Geometry.Vector2D = { x: 1, y: 2 };
const vector3D: Geometry.Vector3D = { x: 1, y: 2, z: 3 };
console.log(vector2D); // { x: 1, y: 2 }
console.log(vector3D); // { x: 1, y: 2, z: 3 }
Pode ocorrer via export/import, ou via reference (exemplo abaixo).
utils.ts:
function greet(name: string): string {
return `Hello, ${name}!`;
}
app.ts:
///<reference path="./utils.ts" />
console.log(greet("Alice"));
mkdir to-do-list
cd to-do-list
mkdir src src/models src/services
npm init -y
npm install --save-dev typescript
npm install --save-dev @types/node
npx tsc --init
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
}
export interface Task {
id: number;
title: string;
completed: boolean;
createdAt: Date;
}
import { Task } from "../models/Task";
export class TaskService {
private tasks: Task[] = [];
private nextId: number = 1;
addTask(title: string): Task {
const newTask: Task = {
id: this.nextId++,
title,
completed: false,
createdAt: new Date(),
};
this.tasks.push(newTask);
return newTask;
}
listTasks(): Task[] {
return this.tasks;
}
completeTask(id: number): boolean {
const task = this.tasks.find((task) => task.id === id);
if (task) {
task.completed = true;
return true;
}
return false;
}
removeTask(id: number): boolean {
const index = this.tasks.findIndex((task) => task.id === id);
if (index !== -1) {
this.tasks.splice(index, 1);
return true;
}
return false;
}
}
import { TaskService } from "./services/TaskService";
const taskService = new TaskService();
console.log("Adicionando tarefas:");
const task1 = taskService.addTask("Estudar TypeScript");
const task2 = taskService.addTask("Desenvolver um projeto");
console.log(task1);
console.log(task2);
console.log("\nLista de tarefas:");
console.log(taskService.listTasks());
console.log("\nConcluindo a tarefa com ID 1:");
taskService.completeTask(1);
console.log(taskService.listTasks());
console.log("\nRemovendo a tarefa com ID 2:");
taskService.removeTask(2);
console.log(taskService.listTasks());
npx tsc
node dist/index.js
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
Elaborado por Mateus Schwede
ubsocial.github.io