{"id":22323040,"url":"https://github.com/frontendfixer/typescript-tutorial","last_synced_at":"2025-03-26T05:12:41.913Z","repository":{"id":183002038,"uuid":"669446307","full_name":"frontendfixer/typescript-tutorial","owner":"frontendfixer","description":"typescript-tutorial with code and chapter","archived":false,"fork":false,"pushed_at":"2023-07-22T17:04:18.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-31T06:48:14.005Z","etag":null,"topics":["react","tutorial","typescript"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/frontendfixer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2023-07-22T09:58:12.000Z","updated_at":"2023-07-22T10:28:48.000Z","dependencies_parsed_at":"2025-01-31T06:48:17.752Z","dependency_job_id":"4c98f42a-d953-461b-beac-5cfff75eb78b","html_url":"https://github.com/frontendfixer/typescript-tutorial","commit_stats":null,"previous_names":["frontendfixer/typescript-tutorial"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Ftypescript-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Ftypescript-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Ftypescript-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Ftypescript-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frontendfixer","download_url":"https://codeload.github.com/frontendfixer/typescript-tutorial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245591587,"owners_count":20640692,"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":["react","tutorial","typescript"],"created_at":"2024-12-04T01:09:15.260Z","updated_at":"2025-03-26T05:12:41.886Z","avatar_url":"https://github.com/frontendfixer.png","language":null,"readme":"# typescript-tutorial\n\nThis is a _collection_ of `code` from a Youtube video of [Dave Gray](https://github.com/gitdagray) || [video link](https://www.youtube.com/playlist?list=PL0Zuz27SZ-6NS8GXt5nPrcYpust89zq_b)\n\nYou can also [check out](https://github.com/gitdagray/typescript-course) his Github page for details lessons.\n\n### Author Links\n\n✅ [Check out his YouTube Channel](https://www.youtube.com/DaveGrayTeachesCode).\n\n🚩 [Subscribe to his channel](https://bit.ly/3nGHmNn)\n\n🚀 Dave Gray Social Links:\n\n- [Twitter](https://twitter.com/yesdavidgray)\n- [LinkedIn](https://www.linkedin.com/in/davidagray/)\n- [Blog](https://yesdavidgray.com)\n- [Reddit](https://www.reddit.com/user/DaveOnEleven)\n\n---\n\n## Jump to specific Chapter\n\n- [typescript-tutorial](#typescript-tutorial)\n  - [Author Links](#author-links)\n  - [Jump to specific Chapter](#jump-to-specific-chapter)\n  - [Resources](#resources)\n    - [Chapter 1 - Introduction, Setup \\\u0026 Config](#chapter-1---introduction-setup--config)\n    - [Chapter 2 - Basic Types](#chapter-2---basic-types)\n    - [Chapter 3 - Arrays, Tuples, Objects \\\u0026 Enums](#chapter-3---arrays-tuples-objects--enums)\n    - [Chapter 4 - Type Aliases, Literals, Functions \\\u0026 Never Type](#chapter-4---type-aliases-literals-functions--never-type)\n    - [Chapter 5 - Type Assertions \\\u0026 Type Casting](#chapter-5---type-assertions--type-casting)\n    - [Chapter 6 - Classes \\\u0026 Interfaces](#chapter-6---classes--interfaces)\n    - [Chapter 7 - Index Signatures \\\u0026 keyof Assertions](#chapter-7---index-signatures--keyof-assertions)\n    - [Chapter 8 - Generics](#chapter-8---generics)\n    - [Chapter 9 - Utility Types](#chapter-9---utility-types)\n\n## Resources\n\n- [Typescript Official Site](https://www.typescriptlang.org/)\n- [React TypeScript Cheatsheets](https://react-typescript-cheatsheet.netlify.app/)\n  - 🚀 [Github page](https://github.com/typescript-cheatsheets/react)\n\n### Chapter 1 - Introduction, Setup \u0026 Config\n\n```typescript\nlet username = \"Dave\";\nconsole.log(username);\n\nlet a: number = 12;\nlet b: string = \"6\";\nlet c: number = 2;\n\nconsole.log(a / b);\n\nconsole.log(c * b);\n```\n\n### Chapter 2 - Basic Types\n\n```typescript\nlet myName: string = \"Dave\";\nlet meaningOfLife: number;\nlet isLoading: boolean;\nlet album: any;\n\nmyName = \"John\";\nmeaningOfLife = 42;\nisLoading = true;\nalbum = 5150;\n\nconst sum = (a: number, b: string) =\u003e {\n  return a + b;\n};\n\nlet postId: string | number;\nlet isActive: number | boolean;\n\nlet re: RegExp = /\\w+/g;\n```\n\n### Chapter 3 - Arrays, Tuples, Objects \u0026 Enums\n\n```typescript\nlet stringArr = [\"one\", \"hey\", \"Dave\"];\n\nlet guitars = [\"Strat\", \"Les Paul\", 5150];\n\nlet mixedData = [\"EVH\", 1984, true];\n\nstringArr[0] = \"John\";\nstringArr.push(\"hey\");\n\nguitars[0] = 1984;\nguitars.unshift(\"Jim\");\n\nlet test = [];\nlet bands: string[] = [];\nbands.push(\"Van Halen\");\n\n// Tuple\nlet myTuple: [string, number, boolean] = [\"Dave\", 42, true];\n\nlet mixed = [\"John\", 1, false];\n\nmyTuple[1] = 42;\n\n// Objects\nlet myObj: object;\nmyObj = [];\nconsole.log(typeof myObj);\nmyObj = bands;\nmyObj = {};\n\nconst exampleObj = {\n  prop1: \"Dave\",\n  prop2: true,\n};\n\nexampleObj.prop1 = \"John\";\n\ninterface Guitarist {\n  name?: string;\n  active: boolean;\n  albums: (string | number)[];\n}\n\nlet evh: Guitarist = {\n  name: \"Eddie\",\n  active: false,\n  albums: [1984, 5150, \"OU812\"],\n};\n\nlet jp: Guitarist = {\n  active: true,\n  albums: [\"I\", \"II\", \"IV\"],\n};\n\nconst greetGuitarist = (guitarist: Guitarist) =\u003e {\n  if (guitarist.name) {\n    return `Hello ${guitarist.name.toUpperCase()}!`;\n  }\n  return \"Hello!\";\n};\n\nconsole.log(greetGuitarist(jp));\n\n// Enums\n// \"Unlike most TypeScript features, Enums are not a type-level addition to JavaScript but something added to the language and runtime.\"\n\nenum Grade {\n  U = 1,\n  D,\n  C,\n  B,\n  A,\n}\n\nconsole.log(Grade.U);\n```\n\n### Chapter 4 - Type Aliases, Literals, Functions \u0026 Never Type\n\n```typescript\n// Type Aliases\ntype stringOrNumber = string | number;\n\ntype stringOrNumberArray = (string | number)[];\n\ntype Guitarist = {\n  name?: string;\n  active: boolean;\n  albums: stringOrNumberArray;\n};\n\ntype UserId = stringOrNumber;\n\n// Literal types\nlet myName: \"Dave\";\n\nlet userName: \"Dave\" | \"John\" | \"Amy\";\nuserName = \"Amy\";\n\n// functions\nconst add = (a: number, b: number): number =\u003e {\n  return a + b;\n};\n\nconst logMsg = (message: any): void =\u003e {\n  console.log(message);\n};\n\nlogMsg(\"Hello!\");\nlogMsg(add(2, 3));\n\nlet subtract = function (c: number, d: number): number {\n  return c - d;\n};\n\ntype mathFunction = (a: number, b: number) =\u003e number;\n// interface mathFunction {\n//     (a: number, b: number): number\n// }\n\nlet multiply: mathFunction = function (c, d) {\n  return c * d;\n};\n\nlogMsg(multiply(2, 2));\n\n// optional parameters\nconst addAll = (a: number, b: number, c?: number): number =\u003e {\n  if (typeof c !== \"undefined\") {\n    return a + b + c;\n  }\n  return a + b;\n};\n\n// default param value\nconst sumAll = (a: number = 10, b: number, c: number = 2): number =\u003e {\n  return a + b + c;\n};\n\nlogMsg(addAll(2, 3, 2));\nlogMsg(addAll(2, 3));\nlogMsg(sumAll(2, 3));\nlogMsg(sumAll(undefined, 3));\n\n// Rest Parameters\nconst total = (a: number, ...nums: number[]): number =\u003e {\n  return a + nums.reduce((prev, curr) =\u003e prev + curr);\n};\n\nlogMsg(total(10, 2, 3));\n\nconst createError = (errMsg: string): never =\u003e {\n  throw new Error(errMsg);\n};\n\nconst infinite = () =\u003e {\n  let i: number = 1;\n  while (true) {\n    i++;\n    if (i \u003e 100) break;\n  }\n};\n\n// custom type guard\nconst isNumber = (value: any): boolean =\u003e {\n  return typeof value === \"number\" ? true : false;\n};\n\n// use of the never type\nconst numberOrString = (value: number | string): string =\u003e {\n  if (typeof value === \"string\") return \"string\";\n  if (isNumber(value)) return \"number\";\n  return createError(\"This should never happen!\");\n};\n```\n\n### Chapter 5 - Type Assertions \u0026 Type Casting\n\n```typescript\ntype One = string;\ntype Two = string | number;\ntype Three = \"hello\";\n\n// convert to more or less specific\nlet a: One = \"hello\";\nlet b = a as Two; // less specific\nlet c = a as Three; // more specific\n\nlet d = \u003cOne\u003e\"world\";\nlet e = \u003cstring | number\u003e\"world\";\n\nconst addOrConcat = (\n  a: number,\n  b: number,\n  c: \"add\" | \"concat\"\n): number | string =\u003e {\n  if (c === \"add\") return a + b;\n  return \"\" + a + b;\n};\n\nlet myVal: string = addOrConcat(2, 2, \"concat\") as string;\n\n// Be careful! TS sees no problem - but a string is returned\nlet nextVal: number = addOrConcat(2, 2, \"concat\") as number;\n\n//10 as string\n10 as unknown as string;\n\n// The DOM\nconst img = document.querySelector(\"img\")!;\nconst myImg = document.getElementById(\"#img\") as HTMLImageElement;\nconst nextImg = \u003cHTMLImageElement\u003edocument.getElementById(\"#img\");\n\nimg.src;\nmyImg.src;\n```\n\n### Chapter 6 - Classes \u0026 Interfaces\n\n```typescript\nclass Coder {\n  secondLang!: string;\n\n  constructor(\n    public readonly name: string,\n    public music: string,\n    private age: number,\n    protected lang: string = \"Typescript\"\n  ) {\n    this.name = name;\n    this.music = music;\n    this.age = age;\n    this.lang = lang;\n  }\n\n  public getAge() {\n    return `Hello, I'm ${this.age}`;\n  }\n}\n\nconst Dave = new Coder(\"Dave\", \"Rock\", 42);\nconsole.log(Dave.getAge());\n// console.log(Dave.age)\n// console.log(Dave.lang)\n\nclass WebDev extends Coder {\n  constructor(\n    public computer: string,\n    name: string,\n    music: string,\n    age: number\n  ) {\n    super(name, music, age);\n    this.computer = computer;\n  }\n\n  public getLang() {\n    return `I write ${this.lang}`;\n  }\n}\n\nconst Sara = new WebDev(\"Mac\", \"Sara\", \"Lofi\", 25);\nconsole.log(Sara.getLang());\n// console.log(Sara.age)\n// console.log(Sara.lang)\n/////////////////////////////////////\n\ninterface Musician {\n  name: string;\n  instrument: string;\n  play(action: string): string;\n}\n\nclass Guitarist implements Musician {\n  name: string;\n  instrument: string;\n\n  constructor(name: string, instrument: string) {\n    this.name = name;\n    this.instrument = instrument;\n  }\n\n  play(action: string) {\n    return `${this.name} ${action} the ${this.instrument}`;\n  }\n}\n\nconst Page = new Guitarist(\"Jimmy\", \"guitar\");\nconsole.log(Page.play(\"strums\"));\n//////////////////////////////////////\n\nclass Peeps {\n  static count: number = 0;\n\n  static getCount(): number {\n    return Peeps.count;\n  }\n\n  public id: number;\n\n  constructor(public name: string) {\n    this.name = name;\n    this.id = ++Peeps.count;\n  }\n}\n\nconst John = new Peeps(\"John\");\nconst Steve = new Peeps(\"Steve\");\nconst Amy = new Peeps(\"Amy\");\n\nconsole.log(Amy.id);\nconsole.log(Steve.id);\nconsole.log(John.id);\nconsole.log(Peeps.count);\n//////////////////////////////////\n\nclass Bands {\n  private dataState: string[];\n\n  constructor() {\n    this.dataState = [];\n  }\n\n  public get data(): string[] {\n    return this.dataState;\n  }\n\n  public set data(value: string[]) {\n    if (Array.isArray(value) \u0026\u0026 value.every((el) =\u003e typeof el === \"string\")) {\n      this.dataState = value;\n      return;\n    } else throw new Error(\"Param is not an array of strings\");\n  }\n}\n\nconst MyBands = new Bands();\nMyBands.data = [\"Neil Young\", \"Led Zep\"];\nconsole.log(MyBands.data);\nMyBands.data = [...MyBands.data, \"ZZ Top\"];\nconsole.log(MyBands.data);\nMyBands.data = [\"Van Halen\", 5150]; // must be string data\n```\n\n### Chapter 7 - Index Signatures \u0026 keyof Assertions\n\n```typescript\n// Index Signatures\n\n// interface TransactionObj {\n//     readonly [index: string]: number\n// }\n\ninterface TransactionObj {\n  readonly [index: string]: number;\n  Pizza: number;\n  Books: number;\n  Job: number;\n}\n\nconst todaysTransactions: TransactionObj = {\n  Pizza: -10,\n  Books: -5,\n  Job: 50,\n};\n\nconsole.log(todaysTransactions.Pizza);\nconsole.log(todaysTransactions[\"Pizza\"]);\n\nlet prop: string = \"Pizza\";\nconsole.log(todaysTransactions[prop]);\n\nconst todaysNet = (transactions: TransactionObj): number =\u003e {\n  let total = 0;\n  for (const transaction in transactions) {\n    total += transactions[transaction];\n  }\n  return total;\n};\n\nconsole.log(todaysNet(todaysTransactions));\n\n//todaysTransactions.Pizza = 40\n\nconsole.log(todaysTransactions[\"Dave\"]); // undefined\n\n///////////////////////////////////\n\ninterface Student {\n  //[key: string]: string | number | number[] | undefined\n  name: string;\n  GPA: number;\n  classes?: number[];\n}\n\nconst student: Student = {\n  name: \"Doug\",\n  GPA: 3.5,\n  classes: [100, 200],\n};\n\n// console.log(student.test)\n\nfor (const key in student) {\n  console.log(`${key}: ${student[key as keyof Student]}`);\n}\n\nObject.keys(student).map((key) =\u003e {\n  console.log(student[key as keyof typeof student]);\n});\n\nconst logStudentKey = (student: Student, key: keyof Student): void =\u003e {\n  console.log(`Student ${key}: ${student[key]}`);\n};\n\nlogStudentKey(student, \"name\");\n\n/////////////////////////////////\n\n// interface Incomes {\n//     [key: string]: number\n// }\n\ntype Streams = \"salary\" | \"bonus\" | \"sidehustle\";\n\ntype Incomes = Record\u003cStreams, number\u003e;\n\nconst monthlyIncomes: Incomes = {\n  salary: 500,\n  bonus: 100,\n  sidehustle: 250,\n};\n\nfor (const revenue in monthlyIncomes) {\n  console.log(monthlyIncomes[revenue as keyof Incomes]);\n}\n```\n\n### Chapter 8 - Generics\n\n```typescript\nconst echo = \u003cT\u003e(arg: T): T =\u003e arg;\n\n//////////////////////////////////\n\nconst isObj = \u003cT\u003e(arg: T): boolean =\u003e {\n  return typeof arg === \"object\" \u0026\u0026 !Array.isArray(arg) \u0026\u0026 arg !== null;\n};\n\nconsole.log(isObj(true));\nconsole.log(isObj(\"John\"));\nconsole.log(isObj([1, 2, 3]));\nconsole.log(isObj({ name: \"John\" }));\nconsole.log(isObj(null));\n\n///////////////////////////////////\n\nconst isTrue = \u003cT\u003e(arg: T): { arg: T; is: boolean } =\u003e {\n  if (Array.isArray(arg) \u0026\u0026 !arg.length) {\n    return { arg, is: false };\n  }\n  if (isObj(arg) \u0026\u0026 !Object.keys(arg as keyof T).length) {\n    return { arg, is: false };\n  }\n  return { arg, is: !!arg };\n};\n\nconsole.log(isTrue(false));\nconsole.log(isTrue(0));\nconsole.log(isTrue(true));\nconsole.log(isTrue(1));\nconsole.log(isTrue(\"Dave\"));\nconsole.log(isTrue(\"\"));\nconsole.log(isTrue(null));\nconsole.log(isTrue(undefined));\nconsole.log(isTrue({})); // modified\nconsole.log(isTrue({ name: \"Dave\" }));\nconsole.log(isTrue([])); // modified\nconsole.log(isTrue([1, 2, 3]));\nconsole.log(isTrue(NaN));\nconsole.log(isTrue(-0));\n\n////////////////////////////////////\n\ninterface BoolCheck\u003cT\u003e {\n  value: T;\n  is: boolean;\n}\n\nconst checkBoolValue = \u003cT\u003e(arg: T): BoolCheck\u003cT\u003e =\u003e {\n  if (Array.isArray(arg) \u0026\u0026 !arg.length) {\n    return { value: arg, is: false };\n  }\n  if (isObj(arg) \u0026\u0026 !Object.keys(arg as keyof T).length) {\n    return { value: arg, is: false };\n  }\n  return { value: arg, is: !!arg };\n};\n\n//////////////////////////////////////\n\ninterface HasID {\n  id: number;\n}\n\nconst processUser = \u003cT extends HasID\u003e(user: T): T =\u003e {\n  // process the user with logic here\n  return user;\n};\n\nconsole.log(processUser({ id: 1, name: \"Dave\" }));\n//console.log(processUser({ name: 'Dave'}))\n\n///////////////////////////////////////\n\nconst getUsersProperty = \u003cT extends HasID, K extends keyof T\u003e(\n  users: T[],\n  key: K\n): T[K][] =\u003e {\n  return users.map((user) =\u003e user[key]);\n};\n\nconst usersArray = [\n  {\n    id: 1,\n    name: \"Leanne Graham\",\n    username: \"Bret\",\n    email: \"Sincere@april.biz\",\n    address: {\n      street: \"Kulas Light\",\n      suite: \"Apt. 556\",\n      city: \"Gwenborough\",\n      zipcode: \"92998-3874\",\n      geo: {\n        lat: \"-37.3159\",\n        lng: \"81.1496\",\n      },\n    },\n    phone: \"1-770-736-8031 x56442\",\n    website: \"hildegard.org\",\n    company: {\n      name: \"Romaguera-Crona\",\n      catchPhrase: \"Multi-layered client-server neural-net\",\n      bs: \"harness real-time e-markets\",\n    },\n  },\n  {\n    id: 2,\n    name: \"Ervin Howell\",\n    username: \"Antonette\",\n    email: \"Shanna@melissa.tv\",\n    address: {\n      street: \"Victor Plains\",\n      suite: \"Suite 879\",\n      city: \"Wisokyburgh\",\n      zipcode: \"90566-7771\",\n      geo: {\n        lat: \"-43.9509\",\n        lng: \"-34.4618\",\n      },\n    },\n    phone: \"010-692-6593 x09125\",\n    website: \"anastasia.net\",\n    company: {\n      name: \"Deckow-Crist\",\n      catchPhrase: \"Proactive didactic contingency\",\n      bs: \"synergize scalable supply-chains\",\n    },\n  },\n];\n\nconsole.log(getUsersProperty(usersArray, \"email\"));\nconsole.log(getUsersProperty(usersArray, \"username\"));\n\n///////////////////////////////////////\n\nclass StateObject\u003cT\u003e {\n  private data: T;\n\n  constructor(value: T) {\n    this.data = value;\n  }\n\n  get state(): T {\n    return this.data;\n  }\n\n  set state(value: T) {\n    this.data = value;\n  }\n}\n\nconst store = new StateObject(\"John\");\nconsole.log(store.state);\nstore.state = \"Dave\";\n//store.state = 12\n\nconst myState = new StateObject\u003c(string | number | boolean)[]\u003e([15]);\nmyState.state = [\"Dave\", 42, true];\nconsole.log(myState.state);\n```\n\n### Chapter 9 - Utility Types\n\n```typescript\n// Utility Types\n\n// Partial\n\ninterface Assignment {\n  studentId: string;\n  title: string;\n  grade: number;\n  verified?: boolean;\n}\n\nconst updateAssignment = (\n  assign: Assignment,\n  propsToUpdate: Partial\u003cAssignment\u003e\n): Assignment =\u003e {\n  return { ...assign, ...propsToUpdate };\n};\n\nconst assign1: Assignment = {\n  studentId: \"compsci123\",\n  title: \"Final Project\",\n  grade: 0,\n};\n\nconsole.log(updateAssignment(assign1, { grade: 95 }));\nconst assignGraded: Assignment = updateAssignment(assign1, { grade: 95 });\n\n// Required and Readonly\n\nconst recordAssignment = (assign: Required\u003cAssignment\u003e): Assignment =\u003e {\n  // send to database, etc.\n  return assign;\n};\n\nconst assignVerified: Readonly\u003cAssignment\u003e = {\n  ...assignGraded,\n  verified: true,\n};\n\n// NOTE: assignVerified won't work with recordAssignment!\n// Why? Try it and see what TS tells you :)\n\nrecordAssignment({ ...assignGraded, verified: true });\n\n// Record\nconst hexColorMap: Record\u003cstring, string\u003e = {\n  red: \"FF0000\",\n  green: \"00FF00\",\n  blue: \"0000FF\",\n};\n\ntype Students = \"Sara\" | \"Kelly\";\ntype LetterGrades = \"A\" | \"B\" | \"C\" | \"D\" | \"U\";\n\nconst finalGrades: Record\u003cStudents, LetterGrades\u003e = {\n  Sara: \"B\",\n  Kelly: \"U\",\n};\n\ninterface Grades {\n  assign1: number;\n  assign2: number;\n}\n\nconst gradeData: Record\u003cStudents, Grades\u003e = {\n  Sara: { assign1: 85, assign2: 93 },\n  Kelly: { assign1: 76, assign2: 15 },\n};\n\n// Pick and Omit\n\ntype AssignResult = Pick\u003cAssignment, \"studentId\" | \"grade\"\u003e;\n\nconst score: AssignResult = {\n  studentId: \"k123\",\n  grade: 85,\n};\n\ntype AssignPreview = Omit\u003cAssignment, \"grade\" | \"verified\"\u003e;\n\nconst preview: AssignPreview = {\n  studentId: \"k123\",\n  title: \"Final Project\",\n};\n\n// Exclude and Extract\n\ntype adjustedGrade = Exclude\u003cLetterGrades, \"U\"\u003e;\n\ntype highGrades = Extract\u003cLetterGrades, \"A\" | \"B\"\u003e;\n\n// Nonnullable\n\ntype AllPossibleGrades = \"Dave\" | \"John\" | null | undefined;\ntype NamesOnly = NonNullable\u003cAllPossibleGrades\u003e;\n\n// ReturnType\n\n//type newAssign = { title: string, points: number }\n\nconst createNewAssign = (title: string, points: number) =\u003e {\n  return { title, points };\n};\n\ntype NewAssign = ReturnType\u003ctypeof createNewAssign\u003e;\n\nconst tsAssign: NewAssign = createNewAssign(\"Utility Types\", 100);\nconsole.log(tsAssign);\n\n// Parameters\n\ntype AssignParams = Parameters\u003ctypeof createNewAssign\u003e;\n\nconst assignArgs: AssignParams = [\"Generics\", 100];\n\nconst tsAssign2: NewAssign = createNewAssign(...assignArgs);\nconsole.log(tsAssign2);\n\n// Awaited - helps us with the ReturnType of a Promise\n\ninterface User {\n  id: number;\n  name: string;\n  username: string;\n  email: string;\n}\n\nconst fetchUsers = async (): Promise\u003cUser[]\u003e =\u003e {\n  const data = await fetch(\"https://jsonplaceholder.typicode.com/users\")\n    .then((res) =\u003e {\n      return res.json();\n    })\n    .catch((err) =\u003e {\n      if (err instanceof Error) console.log(err.message);\n    });\n  return data;\n};\n\ntype FetchUsersReturnType = Awaited\u003cReturnType\u003ctypeof fetchUsers\u003e\u003e;\n\nfetchUsers().then((users) =\u003e console.log(users));\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontendfixer%2Ftypescript-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrontendfixer%2Ftypescript-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontendfixer%2Ftypescript-tutorial/lists"}