Share
Explore

Lecture Lab Workbook introducing TypeScript for creating object-oriented Node.js applications, leading up to SOA distributed systems concepts.

Related Labs:

Running TypeScript directly at the Command Line with ts-node


For the Project:

I will assign to each Team a Business Domain.
You will apply the mechanics of Business Process Analysis, OOAD and UML to constructing a TYPESCRIPT application with MONGO DB as the data persistence layer.

JULY 18 Lab :
Constructing UML diagram from your OOAD which you forward generate as TypeScript objects, and your data structure is going to be MongoDB.

More Advanced lab for Week 10:

Pre-Amble:

Limitations of JavaScript: Does not have types or classes.
Therefore we can NOT do UML domain driven programming, generating OBJECTS from UML, because JavaScript does not have OBJECTS.
As we move into doing the Project: SOA Distributed Web Application:
Everyone will setup several servers on their Operating System.
Your SOA architecture will simulate a business domain passing OBJECTS around various servers.
We will communicate information around by passing OBJECTS as the containers of data AND BUSINESS PROCESSES.

megaphone

Dive into the intricate world of software architecture as we shed light on the differences and connections between Microservices and Model View Controller (MVC). Understand how MVC's code-oriented nature integrates into the broader framework of Service-Oriented Architecture (SOA), and learn about the innovative strategies employed by SOA in discovering and connecting to other services.

The goal is to create distributed Enterprise Applications.

Discover the transformation of monolithic structures into independent algorithms each dwelling within its unique containers, communicating via TCP/IP and Ports. Join us for this enlightening exploration in understanding the individual and collective roles each plays within software architectures.



Apply the processes of OOAD : our TypeScript OBJECTS going to become Business OBJECTS — meaning — TypeScript OBJECTS depicting Business Processes expressed in BPEL.
Boxes containing business data and processes.

Therefore, that is why we need TypeScript.


Here's a 10-lesson progression that starts from the basics and builds up to moving objects between servers:

This lab workbook provides a structured approach to learning TypeScript and object-oriented Node.js development, culminating in a basic distributed system where objects can be moved between servers. This is your Project.

Each lesson builds upon the previous ones, gradually introducing more complex concepts.

Remember to encourage students to experiment with the code, test different scenarios, and ask questions if they encounter any difficulties. This hands-on approach will help solidify their understanding of these concepts.

TypeScript and Object-Oriented Node.js:

Our tool set for building Enterprise Distributed Systems

TypeScript was developed original to serve the goal of getting the REACT Web Projects to work.
TypeScript is a super set of JavaScript.
TS had to be backward compatible with older browser.
Workaround: The Babel Transpiler.
There are 2 modalites in which we can use TypeScript.
Use the tsc compiler. Transpilation needs : Turn TypeScript into JavaScript.

Why go through TypeScript in this Case?

If I'm working in a strongly object oriented language like TypeScript, I can use UML, and I can use object oriented software engineering methodologies like unified process, which you're going to be required to learn in connection with doing the project. And therefore I can get all the benefits of doing object oriented analysis and design, which means I can create much more robust, scalable, secure and easy to maintain code, faster then I can let my TypeScript compiler, my Babel transpiler, do whatever it wants to do, what's actually called method munging. It can turn that into old, boring JavaScript that can run in every browser in the world. Because as a programmer, I don't care what happens at runtime, just so long as it works, I care about how quickly and efficiently I can produce applications so s. So, working with TypeScript, and the front end, where the front end is me, the programmer, and then Babel transpiling it down to plain old JavaScript to run in the back end, happens to be a very efficient methodology. It's a very efficient way to do things.


Objective:

Understand what TypeScript is and how it relates to JavaScript.

Steps:

Install Node.js from
Open Visual Studio Code
Create a new folder for your project
Open a terminal in VS Code (Terminal > New Terminal)
Run npm init -y to create a package.json file
Install TypeScript: npm install -g typescript
Create a file named hello.ts
Add the following code:
let message: string = "Hello, TypeScript!";
console.log(message);

Compile the TypeScript file: tsc hello.ts
Run the resulting JavaScript: node hello.js

Exercise:

Modify the message and experiment with different variable types (number, boolean).

*** Lesson 2: TypeScript Configuration

Objective:

Set up a TypeScript project with proper configuration.

Steps:

In your project folder, create a TypeScript configuration file: tsc --init
Open tsconfig.json and ensure these options are set:
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./src",
"strict": true
}
}
Create a src folder in your project
Move hello.ts into the src folder
Compile the project: tsc
Run the compiled file: node dist/hello.js

Exercise:

Create a new TypeScript file in the src folder, compile the project, and run the new file.
image.png

megaphone

What your tsconfig.json file could look like:

{
"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 legacy experimental 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": "./src", /* Specify the root folder within your source files. */

// "moduleResolution": "node10", /* 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. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "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. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "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. */
// "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. */
// "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. */

/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "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. */
}
}


Lesson 3: Classes in TypeScript

Objective: Understand and create classes in TypeScript.

Steps:

In the src folder, create a file named person.ts
Add the following code:
class Person {
private name: string;
private age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

public introduce(): string {
return `Hi, I'm ${this.name} and I'm ${this.age} years old.`;
}
}

const john = new Person("John", 30);
console.log(john.introduce());
Compile and run the project

Exercise:

Add a new method to the Person class that calculates and returns the birth year.
megaphone

Add a new method to the Person class that calculates and returns the birth year. Here's how you can modify the person.ts file to include this new method:

class Person {
private name: string;
private age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

public introduce(): string {
return `Hi, I'm ${this.name} and I'm ${this.age} years old.`;
}

// New method to calculate birth year
public getBirthYear(): number {
const currentYear = new Date().getFullYear();
return currentYear - this.age;
}
}

const john = new Person("John", 30);
console.log(john.introduce());
console.log(`John's birth year is approximately ${john.getBirthYear()}`);
In this updated code:
We've added a new method called getBirthYear().
This method calculates the birth year by subtracting the person's age from the current year.
We use new Date().getFullYear() to get the current year dynamically.
The method returns a number representing the approximate birth year.
After the existing code that creates a Person instance and calls introduce(), we've added a line to demonstrate the use of the new getBirthYear() method.
To test this:
Replace the content of your person.ts file with this new code.
Compile the project: Run tsc in your terminal.
Run the compiled JavaScript: node dist/person.js
You should see output similar to this:
Copy
Hi, I'm John and I'm 30 years old.
John's birth year is approximately 1993
(Note: The actual year will depend on when you run the code)
This exercise demonstrates how to add new functionality to an existing class, work with the current date in TypeScript, and perform simple calculations within a method.

Lesson 4: A more complex example: Composition and Inheritance

megaphone

Loading…

Output of “The Dating App”
image.png

Interfaces and Inheritance

Objective:

Learn about interfaces and inheritance in TypeScript.

Steps:

Create a file named shapes.ts in the src folder
Add the following code:
interface Shape {
calculateArea(): number;
}

class Circle implements Shape {
constructor(private radius: number) {}

calculateArea(): number {
return Math.PI * this.radius ** 2;
}
}

class Rectangle implements Shape {
constructor(private width: number, private height: number) {}

calculateArea(): number {
return this.width * this.height;
}
}

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.