Easy Start Guide: TypeScript
Tags: typescript, javascript, beginners, tutorial
Published: 2022-07-31 21:29:00

Before we dive in to TypeScript here are the fundamental concepts you should be familiar with the following JavaScript concepts:

- Variables
- Arrays/Objects/Functions
- Arrow Functions
- Destructuring

## What is TypeScript?
Created by Microsoft, this programming language overcomes some of the challenges of working with Javascript. It is built ontop of Javascript and therefore all Javascript files are technically a TypeScript file.

On a basic level, TypeScript allows you to set variables so that they can only be assignable to a specific datatype.

You can think of plain vanilla JavaScript is the _script_ that tells us what will happen in the play. TypeScript assigns roles (type classification) to the individual actors (variables that we create) so that they know what part they have to play. And if all goes well, our application will perform wonderfully and we may even get a standing ovation.

![standing O](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgsi9s1b3u7uqxiq67ng.gif)

## Why you **SHOULD** use it
Type Script grants us some convenient benefits such as:

- Static Typing: the ability to set a variable's **TYPE** and therefore not allow it to be assigned a value of any other type. Some examples of programming languages that use static typing are: C++, C#, Java. Plain Javascript on the other hand, along with Python and Ruby, use Dynamic Typing, meaning that a variable can be reassigned to a variety of different types of data.

```js
//Static Typing (C++/C#/Java)
int number = 5; // This is fine
number = 'abc'; // this will error
```

```js
//Dynamic Typing (JavaScript, Python, Ruby)
let number = 10; // this works
number = 'a' // this will also work
```
- TypeScript compilation allows for us to find errors in our typescript at compile time as opposed to when we run our application or unit tests.

- Shorthand notations
  - Features not available or not yet available in plain JavaScript that allows us to write cleaner, more efficient code.
- Most code editors nowadays have support for typescript which enables us even more benefits such as:
  - Code Completion
  - Refactoring

## Why you **SHOULDN'T** use it
Browser's inherently do not know how to read TypeScript. Therefore, a transpile process is required to convert your TypeScript code into a browser-readable JavaScript code. However, this process can become especially tedious if you're only working on small and simple components. Therefore it is not typically recommended to use TypeScript in that situation.

## When should you use it?
Simply put, TypeScript's benefits are more apparent when working on medium to large projects and/or with a team of developers to ensure they and yourself don't have any unexpected problems when running your program.

Plain vanilla JavaScript is best when you want to keep your projects simple and finish it in an efficient timeframe.
How to use it

## Getting Started with TypeScript
In your code editor's terminal, you'll use your node package manager (or npm) to install typescript globally by running the command:
`npm i -g typescript`

Once the installation is complete you can verify the installyation by running: 
`tsc -v` and you should receive a response back with the version number.

After verifying that you have type script installed, you can start writing your first TypeScript program by creating a .ts file.

Inside of this new file you can write any JavaScript code and it will be valid TypeScript code. 
example:

```js
let age: number = 28;
```
The syntax is very similar to plain JavaScript but you'll notice a difference with the colon. This denotes the typing of the variable age. 
If you were to try to reassign this value to something other than another number you will get an error. 

Now that we have a single line of TypeScript code, we can run the command: 'tsc <filename.ts>' in order to run our compiler and transpile our .ts file into a .js file. 

You should see the new .js file now and inside of it would look something like this:

```js
var age = 28
```
As you can see, the code you wrote in TypeScript has now been translated into plain javascript. However, by default the TypeScript compiler will set variables to var instead of let or const. If we wish to change this, we will have to make some configurations to our compiler.

## CONFIGURING THE TYPESCRIPT COMPILER

To do this, run 'tsc --init' in your terminal. This will create a tsconfig.json file which you can modify to fit your needs. Below is a snippet of the TypeScript compiler configurations. You do not need to read all of the configurations, but as you can see it is well documented with what each configuration will do.

```js
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Projects */
    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */

    /* Language and Environment */
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
    // "experimentalDecorators": true,                   /* Enable experimental support for TC39 stage 2 draft decorators. */
    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
    // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
    // "moduleResolution": "node",                       /* Specify how TypeScript looks up a file from a given module specifier. */
    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
    // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
    // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
    // "resolveJsonModule": true,                        /* Enable importing .json files. */
    // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

    /* JavaScript Support */
    // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

    /* Emit */
    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
    "outDir": "./dist",                                   /* Specify an output folder for all emitted files. */
    // "removeComments": true,                           /* Disable emitting comments. */
    // "noEmit": true,                                   /* Disable emitting files from a compilation. */
    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
    // "importsNotUsedAsValues": "remove",               /* Specify emit/checking behavior for imports that are only used for types. */
    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
    // "newLine": "crlf",                                /* Set the newline character for emitting files. */
    // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
    // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */
    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
    // "preserveValueImports": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

    /* Interop Constraints */
    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */
    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
    // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
    // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */
    // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
    // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */
    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */
    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
    // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */
    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */

    /* Completeness */
    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

```
To use a configuration you will just have to uncomment the line you wish to configure. There are a lot of configurations in this file that you don't necessarily need to understand but the more common ones are:

- **target**: You can set this to any ES version (ES2016/ES2017/ES2018...). ES2016 is a very common and most used version so that will likely work best for you in most situations.
- **rootDir**: The configuration that specifies the directory that contains our src files. By default it is set to "./" which represents the current folder.
- **outDir**: This configuration specifies the directory where our transpiled .js files will be sent.
- **removeComments**: If you add this configuration and keep it set to true, any comments you typed in your TypeScript code will not be transpiled in your .js files. 
- **noEmitOnError**: This will stop the compiler if there are any errors in our TypeScript code. 

After you finish setting up your configuration, you can now run 'tsc' instead of 'tsc <filename.ts>' to transpile ALL .ts files in your application.


There you have it, you should now be set up to start typing in TypeScript! Of course there are many more nuances to this programming language but I hope this was a good read to get you started! Stay tuned for more information in the future!