{"id":26399669,"url":"https://github.com/igorfonseca05/typescript","last_synced_at":"2025-06-14T19:38:21.233Z","repository":{"id":282868543,"uuid":"949916755","full_name":"igorfonseca05/Typescript","owner":"igorfonseca05","description":"Repositório dedicado aos estudos de TypeScript, com anotações, exemplos práticos e exercícios do curso. Ideal para revisar conceitos como tipagem estática, interfaces, generics e muito mais. Conteúdo organizado por módulos para facilitar o aprendizado.","archived":false,"fork":false,"pushed_at":"2025-06-09T22:26:22.000Z","size":124,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-09T23:28:29.614Z","etag":null,"topics":["development","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/igorfonseca05.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-17T10:46:58.000Z","updated_at":"2025-06-09T22:26:27.000Z","dependencies_parsed_at":"2025-04-25T12:29:10.102Z","dependency_job_id":"8eef2c6e-3c15-4764-882f-b2206e0e2b63","html_url":"https://github.com/igorfonseca05/Typescript","commit_stats":null,"previous_names":["igorfonseca05/typescript"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/igorfonseca05/Typescript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorfonseca05%2FTypescript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorfonseca05%2FTypescript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorfonseca05%2FTypescript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorfonseca05%2FTypescript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igorfonseca05","download_url":"https://codeload.github.com/igorfonseca05/Typescript/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorfonseca05%2FTypescript/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259872614,"owners_count":22924628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["development","typescript"],"created_at":"2025-03-17T13:30:51.731Z","updated_at":"2025-06-14T19:38:21.218Z","avatar_url":"https://github.com/igorfonseca05.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![ty](https://github.com/user-attachments/assets/b4234b87-a62e-42dd-ae77-10a391ab1833)\n\n# Seção 1 - Introdução\n\nTypeScript é uma linguagem de programação de alto nível, livre e de código aberto, desenvolvida pela Microsoft que adiciona tipagem estática com anotações de tipo opcionais ao JavaScript.\n\n## Inferindo tipos básicos no typescript\n\n```javascript\nconst nome: string = \"igor\";\nconst idade: number = 29;\nconst adulto: boolean = true;\nconst simbolo: symbol = Symbol(\"qualquer symbol\");\n```\n\nPara os tipos de dados passados por referencia(arrays e objetos) vamos faze:\n\n**1. Arrays**\n\n```javascript\n// As tipagens abaixo são identicas, só muda a forma como são feitas.\nlet ages: Array\u003cnumber\u003e = [2, 3, 4];\nlet ages2: number[] = [2, 3, 4];\n```\n\n**2. Objects**\n\n```javascript\n// As tipagens abaixo são identicas, só muda a forma como são feitas.\n\nconst user: {\n  name: string,\n  email: string,\n  password: string,\n} = {\n  name: \"igor\",\n  email: \"igorfondev@gmail.com\",\n  password: \"123456\",\n};\n```\n\n**3. Funções**\n\n```javascript\nfunction sum(x: number, y: number): number {\n  return x + y;\n}\n\nconst soma: (x: number, y: number) =\u003e number = (x, y) =\u003e {\n  return x + y;\n};\n\ninterface Soma {\n  (x: number, y: number): number;\n}\n\nconst soma2: Soma = (x, y) =\u003e {\n  return x + y;\n};\n```\n\n### Aula 2 - Tipo _Any_\n\nO problema de se manter o _any_ como tipo de uma variavel no ts é que com o any nós podemos fazer qualquer tipo de operação com a variável, uma vez que o ts não tipa o _any_, o que claramente pode trazer problemas para dentro do código, ou seja:\n\n:warning: NUNCA DEIXE NENHUMA VARIÁVEL COMO ANY NO SEU CÓDIGO\n\nUma outra dica dada nessa aula é:\n\n✅: Só tipe a variável se o typeScript reclamar por falta de tipagem\n\n### Aula 3 - Tipo _Void_\n\nÉ a tipagem que fazemos quando queremos que um método e função no ts não retorne nada.\n\n#### Função\n\n```javascript\nfunction sum(...arg: strings[]): void {\n  console.log(args.join(\" \"));\n}\n```\n\n#### Métodos\n\n```javascript\nconst pessoa = {\n  nome: \"igor\",\n  sobrenome: \"Fonseca\",\n\n  getFullName: function (): void {\n    console.log(this.nome + \"\" + this.sobrenome);\n  },\n};\n```\n\nNos exemplos acima não há retorno nenhum e com o uso do void o typescript não lança um erro devido a tipagem.\n\n### Aula 4 - Tipo Object(Objetos em geral)\n\nNessa aula vamos aprender como podemos tipar objetos dentro do typescript\n\n```javascript\n\n```\n\n# Seção 2 - Fundamentos do Typescript\n\n### 20 - O que são tipos?\n\nComo foi mostrado acima, a principal função so typescript é determinar tipos para os dados do nosso projeto, seja para uma variavel, array, objetos e assim por diante.\n\n- Em TypeScript a principal função é **determinar tipos para os dados**; ✅\n- Isso vai garantir a **qualidade do código**; 💡\n- Além de fazer o TS nos **ajudar na hora do desenvolvimento**; 🛠️\n- Ou seja, precisamos **definir corretamente o tipo** das variáveis, dos retornos das funções, das manipulações de dados; 📌\n- Consequentemente, teremos um software melhor programado e é este o principal intuito do TS; 🎯\n\n### 21 - Tipos primitivos\n\nOs tipos primitivos no typescript são os mais simples e são os mesmo do javascript\n\n- **string** → Representa textos, ex: `\"Hello, TypeScript\"`\n- **number** → Números inteiros e decimais, ex: `42` ou `3.14`\n- **boolean** → Verdadeiro ou falso, ex: `true` ou `false`\n- **null** → Representa ausência de valor\n- **undefined** → Variável declarada sem valor atribuído\n- **bigint** → Números inteiros muito grandes, ex: `9007199254740991n`\n- **symbol** → Valores únicos e imutáveis\n\nTodos eles devem ser escritos em letra **minuscula**\n\n### 23 - Conhecendo o _number_\n\n- Garante que o tipo de um dado seja sempre um tipo number\n\n```javascript\nconst age: number = 29;\n\nconsole.log(age);\n```\n\nSe tentarmos usar algo como \"29\" o typescript vai lançar um error pq age só pode ser do tipo number.\n\n### 24 - Conhecendo o _string_\n\n- Garante que o tipo de um dado seja sempre um tipo string\n\n```javascript\nconst name: string = \"Igor\";\n\nconsole.log(name);\n```\n\nSe tentarmos usar algo como **true** o typescript vai lançar um error pq **name** só pode ser do tipo string.\n\n### 25 - Conhecendo o **boolean**\n\n- Garante que o tipo de um dado seja sempre um tipo string\n\n```javascript\nconst adulto: boolean = true;\n\nconsole.log(adulto);\n```\n\nSe tentarmos usar algo como **Igor** o typescript vai lançar um error pq _adulto_ só pode ser do tipo boolean.\n\n### 25 - TS e aplicação\n\n- Talvez já tenha ficado claro, mas programar com TS é como um **pair programming** 👍;\n- Temos sempre alguém para nos avisar se algo é **feito errado** ⚠️;\n- Depois da compilação, **o TS não tem mais efeito**, ele não pode mais nos ajudar ❌;\n- Por isso há **uma trava de compilação com erros** 🛑;\n- Além de erros, o TS também proporciona **avisos** 🔔;\n\n### 26 - Type inference e Type annotation\n\nSão duas formas diferentes que podemos utilizar para podermos inferir tipo nas nossas variaveis. Por exemplo, o **Type annotation** é a forma cque utilizamos até aqui para podermos inferir tipo, nesse caso o `:`\n\n```ts\nconst name: string = \"Igor\"; // Para inferir o tipo usamos o Type annotation(:)\n```\n\nAgora faremos a tipagem do mesmo exemplo acima usando o Type inference\n\n```ts\nconst name = \"Igor\"; // Usando o Type inference\n```\n\naqui o Typescript irá inferir o tipo da variável e manterá esse método durante toda criação do seu projeto.\n\n### 27 - Gerando arquivo de configuração\n\n- O TS pode ser configurado de **muitas maneiras** 🔧;\n- Mas para isso precisamos do **arquivo de configuração** 📄;\n- Para criar ele utilizamos:\n  ```sh\n  tsc --init\n  ```\n\n### 28 - Compilação automática\n\nPara ativarmos o _watch mode_ do typescript, no terminal fazemos:\n\n    tsc -w\n\nagora toda vez que salvarmos nosso arquivo, ele será compilado automáticamente sem precisar fazer isso manualmente.\n\n### 28 - Conclusão da seção\n\n# Seção 3 - Avançando em tipos\n\n### 31 - Arrays\n\nEssa é a sintax mais utilizada para definir arrays no ts\n\n```javascript\nconst numbers: number[] = [1, 2, 3, 4];\n\nconsole.log(numbers);\n\nconst nomes: string[] = [\"igor\", \"fonseca\"];\n\nconsole.log(nomes);\n```\n\n### 32 - Outra sintax para array\n\nA sintax abaixo é menos utilizada, porém é importante ser conhecida\n\n```javascript\nconst num: Array\u003cnumber\u003e = [1, 2, 3, 4];\n\nconsole.log(num);\n```\n\n### 33 - O tipo any\n\nEsse é tipo que satisfaz qualquer tipo no ts, devemos evitar ao máximo usar essa tipagem porque foge completamente do que buscamos fazer com o typescript.\n\n```javascript\nconst arr1: any = [1, \"igor\", true, [\"igor\", 4]];\n```\n\n### 34 - Tipo de Parâmetro\n\nO tipo de parâmetro define qual tipo de dado uma função pode receber como argumento. Isso ajuda a evitar erros, garantindo que apenas valores esperados sejam passados para a função.\n\n### Exemplo:\n\n```ts\nfunction showMessage(message: string) {\n  console.log(message);\n}\n\nshowMessage(\"Olá, TypeScript!\"); // Correto\nshowMessage(123); // Erro: número não é string\n```\n\n## 35 - Tipo de retorno\n\nO tipo de retorno define qual tipo de valor a função deve devolver. Se o retorno não corresponder ao tipo esperado, o TypeScript exibirá um erro.\n\n### Exemplo:\n\n```ts\nfunction sum(a: number, b: number): number {\n  return a + b;\n}\n\nconst resultado = sum(5, 10); // Correto, retorna um número\n```\n\nSe uma função não retornar nada, o TypeScript usa o tipo void:\n\n```ts\nfunction logMessage(message: string): void {\n  console.log(message);\n}\n```\n\n## 36 - Funções anônimas\n\nFunções anônimas são aquelas sem um nome explícito, geralmente usadas como expressões de função ou em callbacks.\n\n```ts\nconst multiply = function (a: number, b: number): number {\n  return a * b;\n};\n\nconsole.log(multiply(4, 5)); // Retorna 20\n```\n\nExemplo de função anônima com arrow function:\n\n```ts\nconst divide = (a: number, b: number): number =\u003e a / b;\n\nconsole.log(divide(10, 2)); // Retorna 5\n```\n\n## 37 - Tipos de Objetos\n\nEm TypeScript, podemos definir o tipo de um objeto especificando suas propriedades e seus respectivos tipos. Isso garante que o objeto sempre siga a estrutura esperada.\n\n### 📌 Definição básica de um objeto\n\n```ts\nconst user: { name: string; age: number } = {\n  name: \"Igor\",\n  age: 29,\n};\n\nconsole.log(user.name); // Igor\nconsole.log(user.age); // 29\n```\n\nUm outro exemplo seria o de usar objetos como parametros de funções\n\n```ts\nfunction passCoordinates(coord: {x: number, y: number}) {\n  console.log(x,y)\n}\n\npassCoordinate({1,2})  ✅\npassCoordinate('oi')  ❌\n```\n\n## 38 - Propriedades Opcionais\n\nEm TypeScript, podemos definir propriedades opcionais em um objeto usando `?`. Isso significa que a propriedade **pode ou não estar presente**, sem causar erros.\n\n### 📌 Definição de uma propriedade opcional\n\n```ts\ntype User = {\n  name: string;\n  age: number;\n  email?: string; // O '?' torna essa propriedade opcional\n};\n\nconst user1: User = {\n  name: \"Ana\",\n  age: 25,\n}; // ✅ Válido, pois 'email' é opcional\n\nconst user2: User = {\n  name: \"Carlos\",\n  age: 30,\n  email: \"carlos@email.com\",\n}; // ✅ Também válido\n```\n\n## 39- Validação de parâmetro opcional\n\nPrecisamos validar esses campos porque quando usamos o argumento opcional o typescrit não se responsabiliza mais pelo que ocorre dentro do nosso código.\n\n```js\nfunction advancedGreeting(firstName: string, lastName?: string) {\n  if (lastName !== undefined) {\n    // aqui não verifacamos o tipo e sim se ele foi enviado\n    return console.log(`Olá ${firstName} ${lastName}, tudo bem?`);\n  }\n\n  return `Olá, ${firstName}, tudo bem?`;\n}\n```\n\n## 40- Union type\n\nO Union type é uma alternativa melhor do que o any, onde podemos determinar dois tipos para um dado\n\na sintax é:\n\n    number | string\n\nabaixo mostramos um exemplo\n\n```ts\nfunction balance(balance: string | number) {\n  console.log(`Seu extrato é: ${balance}`);\n}\n\nconst arrDiverso number | string = ['igor', 29]\n```\n\n## 41- Avançando em Union types\n\nPodemos utilizar condicionais para validação do tipo de union types e usar o `typeof` para poder analisar o tipo de dado.\n\n```ts\nfunction showUserRole(role: boolean | string) {\n  if (typeof role === \"Boolean\") {\n    return \"Usuário não aprovado\";\n  }\n\n  return `A função do usuário é: ${admin}`;\n}\n```\n\nNa função acima existe a verificação se o usuário é admin ou não, não existe true, somente false e \"admin\".\n\n## 42- Type alias\n\nÉ uma forma de renomear uma sentença do typescript\n\n```ts\ntype UserId = string | ObjectId;\n\nfunction getUserId(id: UserId) {\n  console.log(`Bem vindo, seu id é ${id}`);\n}\n```\n\n## 43- Introdução às Interfaces\n\nInterface no typescript é uma outra forma de nomear tipo de objetos no ts. Além de nomear podemos também escolher quais propriedades e seus tipos\n\n```ts\ninterface Point {\n  x: number;\n  y: number;\n  z: number;\n}\n\nfunction coord(coordinates: Point) {\n  console.log(\n    `As coordenadas do ponto são X: ${coordinates.x}, Y: ${coordinates.y}, Z:${coordinates.y}`\n  );\n}\n\ncoord(x: 25, y: 45: z: 69)\n```\n\n## 44- Type alias x Interface\n\nNão existe diferenças significativas entre ambas, a única diferença de fato é que a interface pode ser alterada durante o código enquanto o type alias não pode.\n\n### Interface\n\n```ts\ninterface Person {\n  name: string;\n}\n\n// Pode ser modificada ✅\ninterface Person {\n  age: number;\n}\n\nconst person: Person = { name: \"Matheus\", age: 30 };\n\nconsole.log(person);\n```\n\n### Type Alias\n\n```ts\ntype Person = {\n  name: string\n}\n\n❌ // aqui o ts lançaria um erro, pois não é possível reescrever o type\n type Person = {\n  age: number\n}\n\nconst person : Person = {name: 'Matheus', age: 30}\n\nconsole.log(person)\n```\n\n## 45- Literal Types\n\nLiteral Types no TypeScript são tipos que representam valores específicos e imutáveis. Em vez de um tipo genérico (como string ou number), um literal type restringe o valor a um conjunto específico.\n\n```ts\nlet status: \"success\" | \"error\"; // Só pode ser \"success\" ou \"error\"\nstatus = \"success\"; // válido\nstatus = \"failure\"; // erro, \"failure\" não é um valor permitido\n\nlet level: 1 | 2 | 3; // Só pode ser 1, 2 ou 3\nlevel = 2; // válido\nlevel = 4; // erro, 4 não é um valor permitido\n\nlet isActive: true; // Só pode ser true\nisActive = false; // erro, não é permitido\n```\n\nUso com funções\n\n```ts\nfunction logStatus(status: \"active\" | \"inactive\"): void {\n  console.log(status);\n}\n\nlogStatus(\"active\"); // válido\nlogStatus(\"inactive\"); // válido\nlogStatus(\"pending\"); // erro, \"pending\" não é permitido\n```\n\n## 46- Non null assertion operator\n\nO Non-null Assertion Operator (!) no TypeScript é usado para indicar que uma variável ou expressão não pode ser null ou undefined, mesmo que o compilador do TypeScript não consiga garantir isso. Ou seja, ele força o TypeScript a tratar o valor como não nulo, ignorando a verificação de nulidade.\n\n**Exemplo comum:** Quando você está acessando elementos do DOM ou lidando com valores que você sabe que sempre estarão presentes após um certo ponto do código.\n\n### Sintaxe\n\n```ts\nvalor!; // A expressão valor não será null ou undefined\n```\n\n### Exemplo\n\n```ts\nlet nome: string | null = \"João\";\n\n// Usando o operador de asserção\nconsole.log(nome!.toUpperCase()); // Aqui, garantimos que 'nome' não é null, então podemos chamar toUpperCase sem erro\n```\n\n## 47- BigInt\n\nbigint é usado para representar números inteiros muito grandes, que excedem o limite de number (que é 2^53 - 1).\n\n```ts\nconst big1: bigint = 9007199254740991n;\nconst big2: bigint = BigInt(\"9007199254740992\");\n\nconst result = big1 + big2;\nconsole.log(result); // 18014398509481983n\n```\n\n⚠️ Observações:\n\n- Você pode usar o sufixo n ou o construtor BigInt().\n\n- bigint não pode ser misturado com number diretamente.\n\n```ts\nconst normalNumber = 10;\n// const wrong = big1 + normalNumber // ❌ Erro\n```\n\n## 48- Symbol\n\nSymbol é um tipo primitivo único e imutável, usado como identificadores exclusivos, mesmo que tenham a mesma descrição.\n\n```ts\nconst sym1 = Symbol(\"id\");\nconst sym2 = Symbol(\"id\");\n\nconsole.log(sym1 === sym2); // false — são únicos\n```\n\nUsando como chave de objeto:\n\n```ts\nconst id = Symbol(\"userId\");\n\nconst user = {\n  name: \"Igor\",\n  [id]: 12345,\n};\n\nconsole.log(user[id]); // 12345\n```\n\nVantagens:\n\n- Evita colisões de nomes em objetos.\n\n- Muito usado em bibliotecas/ferramentas internas (ex: no React, com $$typeof internamente).\n\n# Seção 4. Narrowing\n\n### 53. O que é narrowing?\n\nNarrowing no TypeScript é o processo de reduzir um tipo mais amplo para um tipo mais específico dentro de um bloco de código. Isso é útil para que o TypeScript possa entender melhor quais operações são seguras de executar em uma variável.\n\n### 54. typeof Type Guard\n\nUsamos o typeof para aplicar a tecnica que chamamos de Type Guard, que ajuda o TypeScript a saber se valor é `string` ou `number`, permitindo métodos específicos de cada tipo. Veja o exemplo abaixo:\n\n```ts\nfunction getData(data: string | number): void {\n  if (typeof data === \"string\") {\n    console.log(\"Seu nome é \" + \" \" + data);\n  } else {\n    console.log(`Sua idade é ${data}`);\n  }\n}\n\ngetData(\"Igor\");\ngetData(29);\n```\n\n### 56. Operador instanceof\n\nVerifica se um objeto é de uma determinada classe:\n\n```ts\nclass User {\n  name;\n  age;\n  constructor(name: string, age: number) {\n    (this.name = name), (this.age = age);\n  }\n}\n\nclass FullUser extends User {\n  email;\n  constructor(name: string, age: number, email: string) {\n    super(name, age);\n    this.email = email;\n  }\n}\n\nfunction getUser(user: object) {\n  // Aqui temos um outro tipo de nawworing\n  if (user instanceof User) {\n    console.log(\"É instancia\", user);\n  } else if (user instanceof FullUser) {\n    console.log(`Bem vindo ${user.name}`);\n  }\n}\n\nconst firstUser = new User(\"igor\", 29);\nconst superUser = new FullUser(\"igor\", 29, \"igorfondev@gmail.com\");\n\n// getUser(firstUser)\ngetUser(superUser);\n```\n\n### 57. Operador in\n\nVerifica se uma propriedade existe em um objeto\n\n```ts\ntype Carro = { rodas: number; acelerar: () =\u003e void };\ntype Barco = { velas: number; navegar: () =\u003e void };\n\nfunction mover(veiculo: Carro | Barco) {\n  if (\"rodas\" in veiculo) {\n    veiculo.acelerar();\n  } else {\n    veiculo.navegar();\n  }\n}\n```\n\n# Seção 5 - Funções com Typescript\n\nEste documento é um resumo comentado sobre funções em TypeScript, com foco em boas práticas e recursos do idioma como generics, parâmetros opcionais, callbacks e mais.\n\n### 61. Funções sem retorno (`void`)\n\nEm TypeScript, quando uma função não retorna nenhum valor, usamos o tipo `void`.\n\n```ts\nfunction showName(nome: string): void {\n  console.log(nome);\n}\n\nshowName(\"Igor\");\n```\n\n---\n\n### 62. Callback functions\n\nUma função **callback** é uma função passada como argumento para outra função, para ser executada depois de algum processo.\n\n### ✅ Exemplo com callback que soma dois números:\n\n```ts\nfunction showName(\n  callback: (num1: number, num2: number) =\u003e void,\n  num: number,\n  num2: number\n) {\n  callback(num, num2);\n}\n\nshowName(\n  (num1, num2) =\u003e {\n    console.log(num1 + num2);\n  },\n  2,\n  3\n);\n```\n\n---\n\n### 63. Funções genéricas (Generics)\n\nFunções genéricas permitem que você escreva funções reutilizáveis que funcionam com diferentes tipos de dados.\n\n```ts\nfunction nome\u003cT\u003e(dados: T): T {\n  return {\n    ...dados,\n  };\n}\n\nconst myData = nome(\"oi\");\nconsole.log(myData);\n```\n\n---\n\n### 63. Constraints em Generics\n\nPodemos restringir os tipos aceitos por um generic usando `extends`. Isso é útil para garantir que os valores tenham certas propriedades ou tipos.\n\n```ts\nfunction sum\u003cT extends number | string\u003e(num: T, num2: T): T {\n  // Exemplo omitido: implementação dependeria do tipo\n}\n```\n\n---\n\n### 64. Especificar tipos de argumentos com Generics\n\nVocê pode especificar explicitamente o tipo ao chamar a função:\n\n```ts\nfunction mergeArray\u003cT\u003e(arr1: T[], arr2: T[]): T[] {\n  return arr1.concat(arr2);\n}\n\nconsole.log(mergeArray([1, 2, 3], [4, 5, 6]));\nconsole.log(mergeArray\u003cnumber | string\u003e([1, 2, 3], [\"ana\"]));\n```\n\n---\n\n### 64. Parâmetros opcionais\n\nVocê pode definir parâmetros como opcionais usando `?`.\n\n```ts\nfunction modernGreeting(name: string, greet?: string) {\n  if (greet) {\n    return `Olá ${name} ${greet}, tudo bem?`;\n  }\n  return `Olá ${name}, tudo bem?`;\n}\n\nconsole.log(modernGreeting(\"Igor\"));\n```\n\n---\n\n### 64. Parâmetros com valor default\n\nÉ possível definir valores padrão para parâmetros.\n\n```ts\nfunction somaDefault(num1: number, num = 10) {\n  console.log(num1 + num);\n}\n\nsomaDefault(1); // Output: 11\n```\n\n---\n\n### 65. Tipo `unknown`\n\nO tipo `unknown` é mais seguro do que `any`, pois exige validação antes do uso.\n\n```ts\nfunction doSomething(x: unknown) {\n  console.log(x);\n}\n```\n\n---\n\n### 69. Rest Operator\n\nO operador `...` permite passar múltiplos argumentos como um array.\n\n```ts\nfunction sumAll(...n: number[]) {\n  return n.reduce((number, sum) =\u003e number + sum);\n}\n\nconsole.log(sumAll(1, 2, 3, 4)); // Output: 10\n```\n\n---\n\n📌 **Resumo**: Estes exemplos cobrem funcionalidades essenciais de TypeScript relacionadas a funções, como generics, callbacks, parâmetros opcionais, rest operator e tipos avançados. Eles são amplamente usados em aplicações reais para tornar o código mais robusto, reutilizável e seguro.\n\n# Seção 6 - Entendendo os Objects Types\n\nEste documento reúne conceitos e exemplos comentados sobre **Generics** e **Tipos Avançados** no TypeScript. Ele mostra como utilizar de forma eficaz os recursos de tipagem da linguagem para escrever código mais robusto, seguro e reutilizável.\n\n### 73. O que são Object Types?\n\n**Object types** representam dados que possuem a estrutura de um objeto:\n\n```ts\nconst user = { name: \"igor\", age: 30 };\n```\n\n### 74. Interface como parâmetro\n\nInterfaces permitem **tipar objetos** de forma reutilizável:\n\n```ts\ninterface ProductsProps {\n  name: string;\n  price: number;\n  isAvaliable: boolean;\n}\n\nfunction createProduct(product: ProductsProps): void {\n  console.log(`The ${product.name} is avaliable? ${product.isAvaliable}`);\n}\n\nconst item: ProductsProps = {\n  name: \"Caderno\",\n  price: 22.3,\n  isAvaliable: true,\n};\n```\n\n### 75. Interface com parâmetro opcional\n\nCom `?`, você define uma propriedade como **opcional**:\n\n```ts\ninterface UserProps {\n  name: string;\n  role?: string;\n}\n\nfunction showUser(user: UserProps): void {\n  console.log(`The user ${user.name} is admin? ${user.role ?? true}`);\n}\n```\n\n### 76. Propriedades readonly\n\n`readonly` impede que a propriedade seja alterada:\n\n```ts\ninterface CarProps {\n  nome: string;\n  brand: string;\n  readonly wheel: number;\n}\n```\n\n### 77. Index Signature\n\nPermite declarar um objeto com chaves dinâmicas:\n\n```ts\ninterface UserProps {\n  [index: string]: string;\n}\n\nconst user: UserProps = {\n  name: \"Caio\",\n  age: \"30\",\n};\n```\n\n### 78. Herança de interfaces\n\nUsamos `extends` para herdar propriedades:\n\n```ts\ninterface Products {\n  name: string;\n  price: number;\n}\n\ninterface CleaningProducts extends Products {\n  isAvaliable: boolean;\n}\n```\n\n### 79. Intersection types\n\nUnimos interfaces com `\u0026`:\n\n```ts\ninterface PersonalInfos {\n  name: string;\n}\n\ninterface PrivateInfos {\n  cpf: number;\n}\n\ntype UserInfo = PersonalInfos \u0026 PrivateInfos;\n```\n\n### 80. Readonly array\n\n`ReadonlyArray` impede modificação direta do array:\n\n```ts\nconst nomes: ReadonlyArray\u003cstring\u003e = [\"Igor\", \"Eduardo\", \"Caio\", \"Marcelo\"];\n```\n\n### 81. Tuplas\n\nDefinem a quantidade e tipos de elementos em um array:\n\n```ts\ntype fourNumbers = [number, number, number, number];\nconst nums: fourNumbers = [1, 2, 3, 4];\n\ntype dataMix = [string, string, number];\nconst test: dataMix = [\"Igor\", \"Fonseca\", 30];\n```\n\n### 82. Tuplas com readonly\n\nTuplas que não podem ser alteradas:\n\n```ts\nfunction showNumbers(num: readonly [number, number]) {\n  console.log(num);\n}\n\nshowNumbers([1, 2]);\n```\n\n### 83. Conclusão da seção\n\nEssa seção reforça conceitos fundamentais do TypeScript relacionados a objetos e estruturas de dados, incluindo:\n\n- Tipos de objetos\n- Interfaces\n- Herança e interseção de interfaces\n- Arrays readonly\n- Tuplas\n\nEsses conceitos são essenciais para a construção de aplicações TypeScript bem tipadas e seguras.\n\n# Seção 7 - Criação de tipos\n\n### 86. Revisão: O que são Generics?\n\n**Generics** são usados para criar funções, interfaces ou classes que funcionam com qualquer tipo de dado, mantendo a tipagem forte.\n\n```ts\nfunction showData\u003cT\u003e(arg: T): string {\n  return `O dado é ${arg}`;\n}\n```\n\n### ✅ Vantagens:\n\n- Reutilização de código com segurança de tipos.\n- Evita o uso de `any`, que é menos seguro.\n\n---\n\n### 87. Constraints em Generics\n\nVocê pode limitar os tipos que podem ser usados com generics usando **constraints**.\n\n```ts\nfunction getNome\u003cT extends { name: string }\u003e(obj: T) {\n  return `O campo recebe o nome de ${obj.name}`;\n}\n\nconst name = { name: \"Igor\" };\nconst prod = { label: \"Caderno\" };\n\ngetNome(name); // Funciona\n// getNome(prod)   // Erro, pois não possui a propriedade 'name'\n```\n\n---\n\n### 88. Generics com Interface\n\nInterfaces também podem receber generics para permitir flexibilidade na definição de tipos.\n\n```ts\ninterface Car\u003cT, U\u003e {\n  name: string;\n  wheel: T;\n  engine: U;\n}\n\ntype MyCar = Car\u003cstring, string\u003e;\ntype MySecondCar = Car\u003cnumber, boolean\u003e;\n```\n\nAqui, `Car` pode ser instanciada com diferentes tipos para as rodas (`wheel`) e motor (`engine`), dependendo do contexto.\n\n---\n\n### 89. Type Parameters (em construção)\n\nEste tópico normalmente cobre o uso de parâmetros de tipo mais complexos e o uso de múltiplos generics juntos. Ainda não há exemplo implementado.\n\n---\n\n### 90. Keyof Type Operator (em breve)\n\nO operador `keyof` permite obter as chaves (propriedades) de um tipo como um novo tipo.\n\n---\n\n### 91. Typeof Type Operator (em breve)\n\nUsado para criar tipos baseados em valores existentes com o operador `typeof`.\n\n---\n\n### 92. Indexed Access Types (em breve)\n\nPermite acessar o tipo de uma propriedade específica de um objeto tipo, como `Tipo['propriedade']`.\n\n---\n\n### 93. Conditional Types (em breve)\n\nTipos condicionais permitem criar tipos que mudam de acordo com uma condição.\n\n---\n\n### 94. Template Literal Types (em breve)\n\nPermite criar tipos com base em strings usando templates, como em string interpolation.\n\n---\n\n### 95. Conclusão da seção\n\nEstes conceitos avançados são essenciais para criar bibliotecas, APIs tipadas, e sistemas escaláveis. Estudar Generics e operadores de tipo ajuda a tirar o máximo proveito da segurança de tipos do TypeScript.\n\n# Seção 8 - Classes com Typescript\n\n### 97. Campos em classes\n\nCampos são variáveis declaradas diretamente dentro da classe e representam os dados que os objetos daquela classe armazenam.\n\n```ts\n// Criando classe sem valor de campo inicial\nclass User {\n  name!: string;\n  lastName!: string;\n}\n\nconst user = new User();\n\nuser.name = \"Igor\";\n\nconsole.log(user);\n```\n\n### 98. Constructor\n\nMétodo especial executado automaticamente quando uma instância da classe é criada. É usado para inicializar os membros da classe.\n\n```ts\nclass UserData {\n  name;\n  email;\n\n  constructor(name: string, email: string) {\n    this.name = name;\n    this.email = email;\n  }\n}\n\nconst user2 = new UserData(\"Igor\", \"igor@gmail.com\");\n```\n\n### 99. Propriedades readonly\n\nPropriedades marcadas como readonly só podem ser atribuídas uma vez. Isso ajuda a garantir imutabilidade.\n\n```ts\nclass Car {\n  name;\n  readonly wheel = 4;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n}\nconst fusca = new Car(\"Fusca\");\nconsole.log(fusca);\n```\n\n### 100. Herança e super\n\nPermite que uma classe herde outra. A palavra-chave super é usada para acessar membros da classe base, como seu construtor.\n\n```ts\nclass Prod {\n  name;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n}\n\nclass ProdSize extends Prod {\n  size;\n\n  constructor(name: string, size: number) {\n    super(name);\n    this.size = size;\n  }\n}\n\nconst prod = new ProdSize(\"Cadeira\", 134);\n\nconsole.log(prod);\n```\n\n### 101. Métodos\n\nFunções que definem comportamentos das instâncias da classe.\n\n```ts\nclass Products {\n  prodId;\n  name;\n  price;\n\n  constructor(prodId: number, name: string, price: number) {\n    (this.prodId = prodId), (this.name = name), (this.price = price);\n  }\n}\n\nclass Orders extends Products {\n  idOrder;\n  quantity;\n  constructor(\n    idOrder: number,\n    quantity: number,\n    prodId: number,\n    name: string,\n    price: number\n  ) {\n    super(prodId, name, price);\n    this.idOrder = idOrder;\n    this.quantity = quantity;\n  }\n\n  total() {\n    console.log(this.quantity * this.price);\n  }\n}\n\nconst order = new Orders(1, 2, 23, \"Caderno\", 15.63);\n```\n\n### 02. O this em classes\n\nA palavra-chave this se refere à instância atual da classe e permite acessar seus membros (propriedades e métodos).\n\n```ts\n\n```\n\n### 103. Getters\n\nGetters são usados para retornar dados para o usuário, porém, podemos editar esse dado antes dele ser enviado\n\n```ts\nclass Person {\n  name;\n  lastName;\n  yearOfBithday;\n\n  constructor(name: string, lastName: string, yearOfBithday: number) {\n    this.name = name;\n    this.lastName = lastName;\n    this.yearOfBithday = yearOfBithday;\n  }\n\n  get age() {\n    return new Date().getFullYear() - this.yearOfBithday;\n  }\n}\n\nconst carol = new Person(\"Carol\", \"Fonseca\", 1995);\n\nconsole.log(carol.age);\n```\n\n### 104. Setters\n\nSetters são parecidos com o Getter teóricamente, porem são usados para manipular dados antes de adiciona-los\ndentro da instância da classe\n\n```ts\nclass Person {\n  name;\n  lastName;\n  yearOfBithday;\n\n  constructor(name: string, lastName: string, yearOfBithday: number) {\n    this.name = name;\n    this.lastName = lastName;\n    this.yearOfBithday = yearOfBithday;\n  }\n\n  get age() {\n    return new Date().getFullYear() - this.yearOfBithday;\n  }\n\n  // Aqui recebemos, verificamos e modificamos os dados antes de salvar\n  set addUserName(value: string) {\n    if (value === \"\") {\n      return;\n    }\n    this.name = value.toUpperCase();\n  }\n}\n\nconst carol = new Person(\"Carol\", \"Fonseca\", 1995);\n\n// Para invocar um setter fazemos\ncarol.addUserName = \"carol\";\n// Não usamos ()\n```\n\n### 105. Herdando interfaces\n\nAqui podemos cria uma interface de modo que obriguemos a class a seguir o que está definido na interface usando o `implements`\n\n```ts\ninterface Product {\n  id: number;\n  name: string;\n  quantity: number;\n  price: number;\n  get getTotal(): number;\n}\n\nclass Produto implements Product {\n  id;\n  name;\n  quantity;\n  price;\n\n  constructor(id: number, name: string, quantity: number, price: number) {\n    this.id = id;\n    this.name = name;\n    this.quantity = quantity;\n    this.price = price;\n  }\n\n  get getTotal() {\n    return this.quantity * this.price;\n  }\n}\n\nconst prod = new Produto(1, \"Cadeira\", 2, 56);\n\nconsole.log(prod.getTotal);\n```\n\n### 106. Override de métodos\n\nUm override é usado para substituir o método de uma classe copiando ele dentro de uma subclasse mas alterando sua lógica interna\n\n```ts\nclass ClassMae {\n  // Metodo da class mãe\n  falaAlgo(): void {\n    console.log(\"oi\");\n  }\n}\n\nclass ClassFilha extends ClassMae {\n  // Mesmo método subtituido na classe filha\n  falaAlgo(): void {\n    console.log(\"algo\");\n  }\n}\n\nconst test = new ClassFilha();\n\ntest.falaAlgo();\n```\n\n### 107. Sobre a visibilidade de propriedades e métodos\n\nExplica os diferentes níveis de acesso (public, private, protected) e como eles controlam a visibilidade dos membros da classe.\n\n### 108. Visibilidade public\n\nMembros public são acessíveis de qualquer lugar do código onde a instância estiver disponível, incluindo em subclasses.\n\n```ts\nclass GetId {\n  public id = \"as133asdf135d\";\n}\n\nconst id = new GetId();\n\nconsole.log(id.id);\n```\n\n### 109. Visibilidade protected\n\nMembros protected são acessíveis dentro da própria classe e também nos métodos das subclasses que a estendem.\n\n```ts\n// Class mae\nclass Test {\n  protected userName = \"Lucas Matheus Pereira\";\n}\n// subClass\nclass OutroTest extends Test {\n  showUserName() {\n    console.log(this.userName);\n  }\n}\nconst inst = new OutroTest();\n\ninst.showUserName();\n```\n\n### 110. Visibilidade private\n\nMembros private só são acessíveis dentro da própria classe. Não podem ser acessados nem mesmo por subclasses.\n\n```ts\nclass Private {\n  private name = \"Igor\";\n\n  showName() {\n    console.log(this.name);\n  }\n\n  private getFirstletter() {\n    console.log(this.name[0]);\n  }\n\n  showPrivateMethod() {\n    this.getFirstletter();\n  }\n}\n\nconst privateInst = new Private();\nprivateInst.showName();\n\nprivateInst.showPrivateMethod();\n```\n\n### 111. Static members\n\nPropriedades e métodos estáticos pertencem à classe em si, e não às suas instâncias. São acessados diretamente pela classe.\n\n```javascript\nclass Name {\n  static username = \"igor\";\n}\n\nconsole.log(Name.username);\n```\n\n### 112. Generic class\n\nClasses genéricas usam parâmetros de tipo (como \u003cT\u003e) para funcionar com diferentes tipos de dados de forma segura e reutilizável.\n\n```javascript\nclass Item\u003cT, U\u003e {\n  item1;\n  item2;\n\n  constructor(item1: T, item2: U) {\n    this.item1 = item1;\n    this.item2 = item2;\n  }\n}\n\nconst item = new Item(\"oi\", 2);\nconst item2 = new Item(true, []);\n```\n\n### 113. Parameter properties\n\nSintaxe que permite declarar e inicializar propriedades diretamente nos parâmetros do construtor com modificadores como public.\n\n```ts\nclass Test2 {\n  constructor(public name: string, private age: number) {\n    this.name = name;\n    this.age = age;\n  }\n}\n\nconst test2 = new Test2(\"igor\", 30);\n\nconsole.log(test2.name);\n```\n\n### 114. Class expressions\n\nDeclarações de classe atribuídas a variáveis. São úteis em contextos onde é necessário definir classes de forma dinâmica.\n\n```ts\nconst myperson = class User {\n  name;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n};\n\nconst test3 = new myperson(\"igor\");\n```\n\n### 115. Classe abstrata\n\nClasses abstratas não podem ser instanciadas diretamente. Servem como modelo para outras classes e podem conter métodos abstratos. No exemplo abaixo criei uma classe abstrata e dentro da classe que extende a classe abstrata teve de conter o getName.\n\n```ts\nabstract class UserData2 {\n  abstract getName(): void;\n}\n\nclass UserClass extends UserData2 {\n  name;\n\n  constructor(name: string) {\n    super();\n    this.name = name;\n  }\n\n  getName(): void {\n    console.log(this.name);\n  }\n}\n```\n\n### 116. Relação entre classes\n\nApresenta os diferentes tipos de relação entre classes, como composição, agregação e associação.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorfonseca05%2Ftypescript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figorfonseca05%2Ftypescript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorfonseca05%2Ftypescript/lists"}