{"id":15110343,"url":"https://github.com/pierrebeitz/typescript-workshop","last_synced_at":"2026-01-18T19:09:06.603Z","repository":{"id":70336323,"uuid":"89410999","full_name":"pierrebeitz/typescript-workshop","owner":"pierrebeitz","description":"The fastest way to learn Typescript as a seasoned ES6-Dev","archived":false,"fork":false,"pushed_at":"2017-04-27T10:54:30.000Z","size":37,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-05T16:48:34.827Z","etag":null,"topics":["intro","introduction","learning","learning-by-doing","primer","tutorial","typescript","typescript2"],"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/pierrebeitz.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}},"created_at":"2017-04-25T22:02:40.000Z","updated_at":"2021-09-07T20:01:17.000Z","dependencies_parsed_at":"2023-07-27T06:15:17.003Z","dependency_job_id":null,"html_url":"https://github.com/pierrebeitz/typescript-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pierrebeitz/typescript-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierrebeitz%2Ftypescript-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierrebeitz%2Ftypescript-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierrebeitz%2Ftypescript-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierrebeitz%2Ftypescript-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pierrebeitz","download_url":"https://codeload.github.com/pierrebeitz/typescript-workshop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierrebeitz%2Ftypescript-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28548993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T19:02:06.365Z","status":"ssl_error","status_checked_at":"2026-01-18T19:01:46.239Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["intro","introduction","learning","learning-by-doing","primer","tutorial","typescript","typescript2"],"created_at":"2024-09-25T23:44:24.933Z","updated_at":"2026-01-18T19:09:06.586Z","avatar_url":"https://github.com/pierrebeitz.png","language":"TypeScript","readme":"TypeScript-Workshop\n======================\n\nYou have a basic knowledge of ES6 and want to learn you a TypeScript for great good! Well, you've come to the right place!\n\nThis workshop is meant to help you, a seasoned JS-developer, to get up to speed with TypeScript in no time!\n\n_This is an early version and there is quite some potential to improve the coding-parts in particular._\n\n## Setup\n\n```\nyarn\nyarn start\n```\n\nYou also might want to install a TypeScript-plugin for your editor before starting!\n\n## Getting started\n\nTo following Sections are supposed to be read/worked in order.\n\n### Types\n\nAn example of expressing that color should always be a string:\n\n```typescript\nlet color: string = \"blue\";\n```\n\nAll the types:\n\n* `boolean`\n* `string`\n* `number` - keep in mind that everything in JavaScript is a float.\n* Arrays\n  * `number[]`\n  * `Array\u003cnumber\u003e`\n* Tuples\n  Basically fixed size arrays.\n  * `[string, number | boolean]`\n* Enum\n  Maps readable identifiers to numbers. Starts to count at 0.\n  * `enum Color {Red, Green, Blue}`\n  * `enum Color {Red = 1, Green, Blue}` - starts the enumeration at 1\n  * `enum Color {Red = 1, Green = 2, Blue = 4}` - you can set all the values by hand\n* `any` - thing can be of any kind. this is equivalent to completely skipping type-checks. avoid this!\n* `void` - `void` is a little like the opposite of `any`: the absence of having a type. you may commonly see this as the return type of functions that do not return a value.\n* `null`, `undefined` - By default `null` and `undefined` are subtypes of all other types. That means you can assign `null` and `undefined` to something like `number`.\n  However, when using the `--strictNullChecks` flag, `null` and `undefined` are only assignable to void and their respective types. This helps avoid many common errors. In cases where you want to pass in either a `string` or `null` or `undefined`, you can use a union type (you'll read about them later): `string | null | undefined`.\n* `never` - represents the type of values that never occur. For instance, never is the return type for a function expression or an arrow function expression that always throws an exception or one that never returns:\n\n  ```typescript\n  function error(message: string): never {\n    throw new Error(message);\n    // We `never` get here :)\n  }\n\n  // Inferred return type is never\n  function fail() {\n    return error(\"Something failed\");\n  }\n\n  function infiniteLoop(): never {\n    while (true) {}\n    // We `never` get here. And yes, the compiler is clever enough to know!\n  }\n  ```\n\nIf you should ever need more info, [click here](https://www.typescriptlang.org/docs/handbook/basic-types.html).\n\n### Coding Time!\n\nOur customer just reported a critical issue!\n\nThe App at `http://localhost:3333` falsely greets with `Hello, [object Object]`!\nFortunately Alice recently introduced TypeScript to the project. Unfortunately she was in a hurry and used `any`-annotations everywhere to make the compiler happy!\n\nNarrow down the types in `app/app.ts` and afterwards let the compiler guide you to finding the bug! This has to happen ASAP (as always)!\n\n### Type Assertions\n\nType assertions are a way to tell the compiler \"trust me, I know what I’m doing\". There are 2 ways to do this:\n\n```typescript\nlet strLength: number = (\u003cstring\u003esomeValue).length;\nlet strLength: number = (someValue as string).length;\n```\n\n### Interfaces\n\n* For Objects\n\n```typescript\ninterface Point {\n  readonly x: number;\n  readonly y: number;\n  description: string;\n}\n```\n\n* For Functions\n\n```typescript\ninterface SearchFunc {\n  (source: string, subString: string): boolean;\n}\n\nlet mySearch: SearchFunc;\nmySearch = function(source: string, subString: string) {\n  let result = source.search(subString);\n  return result \u003e -1;\n}\n```\n\n* Indexable Types\n\n```typescript\ninterface StringArray {\n  [index: number]: string;\n}\nlet myArray: StringArray = [\"Bob\", \"Fred\"];\nlet myStr: string = myArray[0];\n```\n\nThis example is not complete and you don't need to know this by heart just yet.\nIf you remember that there's some magic needed to make `myVar[0]` work, you're good.\nIn case you remembered and came to look for more information, please [go somewhere else](https://www.typescriptlang.org/docs/handbook/interfaces.html#indexable-types)!.\n\n* Class Interfaces\n\n```typescript\ninterface ClockInterface {\n  private currentTime: Date;\n  setTime(d: Date);\n  new (hour: number, minute: number);\n}\n\nclass Clock implements ClockInterface {\n  private currentTime;\n  setTime(d) {\n    this.currentTime = d;\n  }\n  constructor(h, m) { } // note how the params don't need to match the names from the interface\n}\n```\n\n### Coding Time!\n\nAdd a `JJ`. A `JJ` is functionally equivalent to a `Greeter` except it always greets with `Yo, digga!`. Let your `JJ` inherit from `Greeter`!\n\nRemember! Work those bullets one after another!\n\n- If your `JJ` now needs a string for instantiation, teach it to work without that!\n- If your `JJ` now contains a constructor, please remove it. You might need to tell the Greeter to just greet `you` by default.\n- If somebody could obtain your default value using something like `(new Greeter())['greeting']` make sure to protect your private parts!\n- Note that `constructor(private greeting : string) {` will automatically create a private instance-variable called `greeting`. Can you golf your code with this?\n- The customer decided that the greeting-prefix (\"Hallo,\") should be customizable! Extract an `Greeting`-Interface and adapt you code.\n\n### Reuse\n\n```typescript\nclass Shape {\n  private position: any;\n}\n\ninterface DrawableShape extends Shape {\n  draw(): void;\n}\n\nclass DrawableCircle implements DrawableShape {\n  radius: number;\n}\n```\n\nYip, that's right! Classes can also extend interfaces and the other way around.\n\nWhen an interface type extends a class type it inherits the members of the class but not their implementations. Interfaces inherit even the private and protected members of a base class.\n\n### Classes\n\n* accessors\n\n```typescript\nlet passcode = \"secret passcode\";\n\nclass Employee {\n  private _fullName: string;\n\n  get fullName(): string {\n    return this._fullName;\n  }\n\n  set fullName(newName: string) {\n    if (passcode \u0026\u0026 passcode == \"secret passcode\") {\n      this._fullName = newName;\n    } else {\n      console.log(\"Error: Unauthorized update of employee!\");\n    }\n  }\n}\n\nlet employee = new Employee();\nemployee.fullName = \"Bob Smith\";\nif (employee.fullName) {\n    console.log(employee.fullName);\n}\n```\n\n* Static Properties\n\n```typescript\nclass JJ {\n  static greeting: string;\n}\n```\n\n* Abstract Classes\n\nThey may not be instantiated directly, but can contain implementation (which interfaces can not).\n\n```typescript\nabstract class Animal {\n  abstract makeSound(): void;\n  move(): void {\n    console.log(\"roaming the earth...\");\n  }\n}\n```\n\n### Functions\n\n* inline-types have other syntax than their interface-pendant\n\n```typescript\nlet myAdd: (baseValue:number, increment:number) =\u003e number = (x, y) =\u003e x + y;;\n```\n\n* Rest Params\n\n```typescript\nfunction buildName(firstName: string, ...restOfName: string[]) {\n```\n### Generics\n\n```typescript\nclass GenericNumber\u003cT\u003e {\n  zeroValue: T;\n  add: (x: T, y: T) =\u003e T;\n}\n\nlet myGenericNumber = new GenericNumber\u003cnumber\u003e();\nmyGenericNumber.zeroValue = 0;\nmyGenericNumber.add = (x, y) =\u003e x + y;\n```\n\n### Advanced Typings\n\n* Intersection Types\n\n`Person \u0026 Serializable \u0026 Loggable` is a `Person` and `Serializable` and `Loggable`.\n\n* Union Types\n\n`Person | JJ ` is either a `Person` or a `JJ`.\n\n```typescript\ninterface Bird {\n  fly();\n  layEggs();\n}\n\ninterface Fish {\n  swim();\n  layEggs();\n}\n\nfunction getSmallPet(): Fish | Bird {}\n```\n\n### Implement Stuff!\n\nYou can safely assume that Bob is working for Customer.\n\nImplement:\n\n* `Eve`    can               `eatCookie`, `callCustomer`, `rantAboutBob`        , `manageDev`\n* `Alice`  can `reviewCode`,              `callCustomer`, `rantAboutBob`, `code`\n* `Bob`    can `reviewCode`, `eatCookie`, `callCustomer`, `rantAboutBob`, `code`\n* `Carol`  can `reviewCode`,              `callCustomer`, `rantAboutBob`, `code`\n* A function that lets someone review some code and then code (to fix that idiot's stuff of course!).\n* A function that lets someone eat a cookie before calling the customer and rant about Bob.\n* A function that lets someone eat a cookie.\n\nExperiment:\n\n* Feed different people to the functions look at the compiler messages.\n* Have at least one intersection type\n* Have at least one union type\n\n### For the Interested Reader\n\nOf course you followed along really vigilant and rightfully ask: \"what if i destructure something and alias it so something named like a type?\".\nI knew you were the type of person that wants to make compilers mad... So let's see:\n\n```typescript\nlet o = {a: \"someString\", b: \"someNumber\"}\n\n// v1 (bad)\nlet { a: string, b: number } = o;\nconsole.log(a)      // =\u003e compiler error: \"Cannot find name 'a'\"\nconsole.log(string) // =\u003e \"someString\". WAIT? WHAT?\n\n// v2 (good)\nlet { a: string, b: number }: { a: string, b: number } = o;\nconsole.log(a)      // =\u003e \"someString\". YAY!\nconsole.log(string) // =\u003e  compiler error: \"Cannot find name 'string\"\n```\n\nAs all valid Javascript is supposed to be valid TypeScript we **CAN** name variables `string` or `number`.\nWhile thinking through the example above you hopefully saw that this is a rather bad idea when using TypeScript.\n\nHere's an equivalent for arrays:\n\n```typescript\nfunction f([first, second]: [number, number]) {}\n```\n\n## Going Further\n\n* Compile a `.ts`-file by hand. Hint: you'll need a TypeScript-project - which means a `tsconfig.json`.\n* Learn about the configuration options in [`tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).\n* Learn about the [Compiler Options](https://www.typescriptlang.org/docs/handbook/compiler-options.html).\n* Learn about [\"Declaration Files\"](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html).\n* Search the interwebs for `tslint` for even more order.\n\n## Feedback\n\n* Rank the workshop from 1 (really bad) to 10 (really good).\n* Think of at least 3 predicates that came on your mind while thinking of a rating.\n* Write down each of the predicates and rank them separately.\n  This might be something like:\n    * The workshop started on time - 2\n    * I don't like those powerpoint-slides - 0\n    * The cat picture made my day - 10\n    * I learned a little - 6\n* Submit this along with any additional Feedback you might have.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierrebeitz%2Ftypescript-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpierrebeitz%2Ftypescript-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierrebeitz%2Ftypescript-workshop/lists"}