Learning More TypeScript Fundamentals
Following Along with Mike North’s Frontend Masters Tutorial
I recently wrote a post on my first steps of learning TypeScript; that blog is available here. This article will be another step in what I’m sure will be a long journey of learning TS. The tutorial that I’m following along with here was shared with me by one of my managers. I’m excited to be able to take my first course with Frontend Masters¹.
TypeScript is an open-source project?!?! Awesome! In my last post I talked about about aspects of the three parts of TS, but didn’t name them directly: Language, Language Server & Compiler. Important to note that not all JavaScript programs can run TypeScript without errors. Again, TypeScript has NO runtime component, it compiles down to readable JS.
The Language Server is what is giving your text editor info that then supports auto-complete and tooltips, etc. The compiler is responsible for the type checking.
TypeScript solidifies developer intent and assumptions. It allows us to add types to variables, functions and classes.
First and foremost: I needed to set up TypeScript globally, and did so with command: npm install typescript -g
SetUp App to Follow Along
There is a repo provided, but I wanted to set up a new project and get more experience with doing so.
In the directory of your choice, type commands mkdir <app-name> , cd <app-name>, mkdir src , (using VSCode as your text editor open the app) code .
Inside the src folder, create a new file index.ts . Then to set up the package.json file type command npm init -y . Type command npm install .
The index.ts file currently has the following code:
Run this command to compile the .ts file to JavaScript with a target of ES2017: tsc src/index.ts --target ES2017- — module commonjs . To run the automatically created index.js file in the browser, user command: node src/index.js . The command to constantly watch and compile the indes.ts file would be: tsc src/index.ts — target ES2017 — module commonjs — watch . (ES2017 just while we are following the tutorial)
SetUp a Configuration File
In the main root folder, create a new file: tsconfig.json .
Run command tsc to adapt the config file. You should now have a lib folder with an index.js, index.d.ts, and an index.js.map file. If you still have an index.js file in src, you can delete it now. The index.js.map file allows you to put a breakpoint in your code during debugging.
Primitive/Basic Types → String, Numbers, Booleans
Literal Types → refer to specific strings and numbers in type positions²:
Top Types → can take any value, play by same rules that JavaScript plays by, be cautious of using any types:
Type Annotation → Anywhere we have a declaration (specifically here with no value), we specify a type:
Simple Arrays
Tuple
— an array of a fixed length and convention (types determined)
***Careful → you don’t get type safety around push on tuples.(anotherArray.push(“a great string”, 3,4 ,5, “a string again”) → won’t throw an error, even though it def should)
Objects
— Instead of key: value, you have key: type, by default all fields are mandatory
Interface: the name for an object structure created:
Logical And (&&) and Or (||) Operators
Intersection Types— And(&)
Intersection Type combines multiple types into one. In TypeScript if one type is intersection of two other types consequently that type will have all properties from two intersected types³.
Union Types — Or(|)
Union Type allows us to declare that a variable can be one of the declared types allowed.
Type Systems & Type Equivalence
TypeScript is a Structural Type System (not a Nominal Type System where x is an instance of a class/type HTMLInputElement) that only regards the shape/structure of an object. Shape: property names and types that are allowed for that property. TypeScript functions only cares about the argument and the return type
Wider vs Narrower
A level of specificity. The widest type is any. Types get narrower from there. Any ‘any’ → Array ‘any[]’ → Array of Strings ‘string[]’ → Array of 3 → ‘[string, string, string]’ — > Nothing ‘never’
Function Types
*Note: Command click will take you from a function to an interface/definition of type. 2 ways a function can be written:
Function return types can be inferred, meaning you don’t have to declare the type after the colon (after the parameter list).
-example:
function funtionName(contact: { name: string }) {…….
Rest Params
New to me is the concept of rest params.
Rest parameter is an improved way to handle function parameter, allowing us to more easily handle various input as parameters in a function. The rest parameter syntax allows us to represent an indefinite number of arguments as an array.⁵
Overload Signatures
With function overloading, you can have multiple functions with the same name but different parameter types and return type. However, the number of parameters should be the same.⁶
The example above has multiple function heads (line 1 and 3).
Lexical Scope
The value of ‘this’ when you invoke a function. In TypeScript, this becomes part of a function signature.
Interfaces & Type Aliases
Type Aliases → giving any type a name, any type that you create with a variable, you can create an alias for:
type StringOrNumber = string | number;
type HasName = { name: string };
**Side note: Self referencing types aren’t allowed
Interfaces → can extend from other interfaces, can describe objects, can describe functions, can describe arrays. They are Javascript values that extend from the JS object type.
An interface doesn’t handle straight primitive types, or operators. Type aliases are more flexible and can handle those. Interfaces can handle JavaScript objects and sub-types.
Type Aliases are sorted out eagerly, where as Interfaces are sorted out lazily (not until we seek it out and use it, do we figure out what the allowable types are for it).
Creating a Dictionary in TypeScript ( an indexed object type)
The workaround for self-referencing types (they don’t work!):
CLASSES
Access Modifier Keywords: (who can access this)
- public → everyone
- protected → me and subclasses
- private → only me
Definite Assignment Operator
The definite assignment assertion is a feature that allows a !
to be placed after instance property and variable declarations to relay to TypeScript that a variable is indeed assigned for all intents and purposes, even if TypeScript’s analyses cannot detect so.⁷
The definite assignment operator is saying to TS: ‘Trust me, I know that I am going to initialize this field correctly somewhere in the class coming up.’
dtslint → Microsofts library to test types
void 0 === undefined
- TypeTypeScript 3 Fundamentals, v2 | Frontend Masters | “https://frontendmasters.com/courses/typescript-v2/”
- Literal Types | TypeScript | “https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types”
- Intersection Types | CodingBlast | “https://codingblast.com/typescript-intersection-types/”
- Union Types | CodingBlast | “https://codingblast.com/typescript-union-types-type-guards-type-aliases/”
- JavaScript | Rest Parameter | Geeks For Geeks | “https://www.geeksforgeeks.org/javascript-rest-operator/”
- TypeScript — Function Overloading | Tutorials Teacher | “https://www.tutorialsteacher.com/typescript/function-overloading”
- Definite Assignment Assertions | TypeScript | “https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html”