I. Basic
Data type:
- boolean/number/string (primitives ): meaning same another programming language.
- bigint/symbol
Assignment:
let myName: string = "Ho Quoc Tri"; //Explicit Type
let myName = "Ho Quoc Tri"; // Implicit, same javascript
let myName: any = "Ho Quoc Tri"; // Type not check, not throw error when assign wrong type
let myName: unknown = " Ho Quoc Tri"; // Same Any but safer than any.
===========================
Typescript - Array
const animals : string [] = [];
animals.push("dog");
-- Create Const Array, cannot change
const animals: read only string[] = ["dog"];
===========================
Typescript - Tuple
let attributeAnimals : [number, string, boolean];
attributeAnimals = [1, "Dog", false];
--Read Only
const attributeAnimals : readonly [number, string, boolean] = [1, "Dog", false];
===========================
Typescript - Object type
const animals : {id: number, name: string, age: number} = {
id: 1,
name : "dogs",
age : 10
}
-- Optional Property
const animals : {id: number, name: string, age?: number} = {
id: 1,
name : "dogs"
}
animals .age = 10;
===========================
Typescript - Enum
//Default enum, first value to 0
and add 1 to each additional value
enum EWEEK {
MONDAY, // default value = 0
TUESDAY, // default value = 1
WEDNESDAY, // default value = 2
THURSDAY, // default value = 3
FRIDAY, // default value = 4
SATURDAY, // default value = 5
SUNDAY // default value = 6
}
// Full initialize value
enum StatusCodes {
NotFound = 404,
Success = 200,
Accepted = 202,
BadRequest = 400
}
===========================
Typescript - Type Alias
We can define primitive type or object, array.
type AnimalAge: number;
type AnimalName: string;
type AnimalStruct = {
age : AnimalAge,
name: AnimalName
}
let age : AnimalAge = 10 ;
let name: AnimalName = "Dogs";
let dogs = {
age : 10,
name: "Dogs"
}
===========================
Typescript - Type Interface
Interface same Type except only apply to Object
interface Animal = {
age : number,
name : string
}
let dog : Animal = {
age : 10,
name : "Dog"
}
//Extend interface
interface Fish extends Animal {
swing: boolean
}
const fish: Fish = {
age : 1,
name: "Fish",
swing: true
}
===========================
Typescript - Union Type
let age : string | number;
function printAge(age: string | number) {
}
===========================
Typescript - Casting
Casting by "as"
let x: unknown = 'hello';
console.log((x as string).length);
-----------
Casting by "<>"
let x: unknown = 'hello';
console.log((<string>x).length);
===========================
Typescript - Classes
class Animal {
private id : number;
protected name : string;
public address : string;
public constructor (id : number) {
this.id = id;
}
}
const dogs = new Animal(1);
dogs.name = "Dog";
-----------
interface ISound {
makeSound : () => string;
}
class Animal implements ISound {
makeSound (): number {
return "Gau Gau";
}
}
-----------
Same JAVA meaning :
abstract class Animal {
public abstract makeSound: string;
}
class Dog extends Animal {
public constructor( ) {
super( );
}
public makeSound(): string{
return "Gau Gau";
}
}
===========================
Typescript - Generics
-- Generics with Function:
function createClazz:<N, S>(numberStudent : <N>, className: <S>) {
return [numberStudent , className];
}
-- Generics with Classes
class NamedValue <T> {
private _value: T | undefined;
}
-- Generics with Type
type AgeAnimal<T> = { age: T };
const age: AgeAnimal<number> = { value: 2 };
-- Generics with a default value.
We can set a default value for generic
class NamedValue <T = string> {
private _value: T | undefined;
}
-- Generics with extends
function createLoggedPair<S extends string | number, T extends string | number>(v1: S, v2: T): [S, T] {
console.log(`creating pair: v1='${v1}', v2='${v2}'`);
return [v1, v2];
}
===========================
Typescript - TypeOf
Check DataType
Type |
Predicate |
string |
typeof s === "string" |
number |
typeof n === "number" |
boolean |
typeof b === "boolean" |
undefined |
typeof undefined === "undefined" |
function |
typeof f === "function" |
array |
Array.isArray(a) |
===========================
Typescript - Utility
-- Partial changes all the properties in an object to be optional.
interface Animal {
id: number,
age: number
}
let animal: Partial<Animal> = {};
animal.id=1;
animal.age=10;
-- Required changes all the properties in an object to be required.
interface Animal {
id: number,
age: number,
name?: string
}
let animal: Required<Animal> = {};
animal.id=1;
animal.age=10;
II. TS Conversion Naming
Ref:
2.1 - Use meaningful variable names.
//BAD
function isBetween(a1: number, a2: number, a3: number): boolean {
return a2 <= a1 && a1 <= a3;
}
//GOOD
function isBetween(value: number, left: number, right: number): boolean {
return left <= value && value <= right;
}
2.2 - Use pronounceable variable names
//BAD
class Subs {
...
}
//GOOD
class Subscription {
...
}
2.3 - Avoid mental mapping
//BAD
const u = getUser();
const s = getSubscription();
const t = charge(u, s);
//GOOD
const user = getUser();
const subscription = getSubscription();
const transaction = charge(user, subscription);
2.3 - Don't add unneed context
//BAD
type Car = {
carMake: string;
carModel: string;
carColor: string;
}
//GOOD
type Car = {
make: string;
model: string;
color: string;
}
2.4 - Naming Convention
- Use camelCase for variable and function names.
- Use camelCase of class members, interface members, methods and methods parameters.
- Use PascalCase for class names and interface names.
// BAD
class foo { }
//GOOD
class Foo { }
- Use PascalCase for enums and camelCase for enum members.
//BAD
enum notificationTypes {
...
}
//GOOD
enum NotificationTypes {
...
}
2.4 - Naming Boolean
- Don't use negative names for boolean variables.
// BAD
const isNotEnabled = true;
// GOOD
const isEnabled = true;
- A prefix like is, are, or has helps every developer to distinguish a boolean from another variable by just looking at it
//BAD
const enabled = true;
//GOOD
const isEnabled = true;
2.5 - Use typescript aliases
-- This will avoid long relative paths when doing imports.
// BAD
import { UserService } from '../../../services/UserService';
// GOOD
import { UserService } from '@services/UserService';
2.6 - Component Structure
Use the following component structure:
- Input properties (i.e. @Input() product: OrderItemModel)
- Output properties (i.e. @Output() changeMade = new EventEmitter(true))
- ViewChild / ViewChildren (i.e. @ViewChild(ChildDirective) child!: ChildDirective)
- HostBinding properties (i.e. @HostBinding('class.valid') get valid() { return this.control.valid; })
- data members (i.e. public isBeingRemoved = false)
- constructor
- lifecycle hooks (following their execution order)
- getters/setters
- event handlers
- other methods
Use the following component accessors order:
- private
- protected
- public
III. TS project
-- Install Typescript Lib
$ npm i typescript --save-dev
-- Init TS Project
$ npx tsc --init
-- Create TS File
$ index.ts
-- Compile TS file => JS File (Crt + ` : to open terminal)
$ npx tsc index.ts
or
$ tsc index.ts
TS file compiles to JS File:
In Visual Studio Code, click on the TS file and CRT + SHIFT + B > Select tsconfig.json > File will compile.
If you want to set default compile config:
CRT + SHIFT + B > Select Setting icon
ts:build > edit
task.json in
.vscode:
Custom Compile output folder:
- tsconfig.json
To easy run in VS, we create a script in package.json:
{
"scripts": {
"Compile-TS": "tsc -p tsconfig.json",
"Run-index": "cd build && node index.js"
},
"devDependencies": {
"typescript": "^5.4.5"
}
}
is updating...