Skip to content

Instantly share code, notes, and snippets.

@navsqi
Last active October 18, 2021 12:48
Show Gist options
  • Select an option

  • Save navsqi/8cbc5223de3c40878999d162f93d9498 to your computer and use it in GitHub Desktop.

Select an option

Save navsqi/8cbc5223de3c40878999d162f93d9498 to your computer and use it in GitHub Desktop.
Belajar typescript
// string
let nama: string = 'Nauval';
nama = 'Shidqi Ganteng';
// number
let umur: number = 12;
umur = 6;
let angka = <number>umur; // cara lain deklarasi variable Type Assertion
console.log('angka', angka);
// boolean
let isMarried: boolean = false;
isMarried = true;
// any
let heroes: any = 'Iron Man';
heroes = 25;
heroes = [];
heroes = {};
heroes = true || false || 'string';
console.log(nama);
// Object
// Interfaces are used to define the structure of variables.
interface Employee {
name: string;
code: number;
}
let employee: Employee = {
name: 'Nauval',
code: 872312,
};
console.log('employee', employee);
// dynamically assign properties to an object
let obj: { [key: string]: any };
obj = {
nim: 1644390040,
nama: 'Shidqi Nauval',
jurusan: 'Sistem Informasi',
};
console.log('obj', obj);
// Type aliases
type CustomType = string | number;
let animeChar: CustomType = 'Bam';
animeChar = 25;
//animeChar = true; // -> Error
// Class Decorator
function Component(options: { id: string }) {
return (target: Function & typeof TestClass) => {
target.prototype.id = options.id;
};
}
// Method Decorator
function MethodTest(
target: Object,
propertyKey: string,
propertyDescriptor: PropertyDescriptor
) {
console.log(target);
console.log(propertyKey);
propertyDescriptor.value = function (...args: any[]) {
return `Hello x Method Decorator ${args}`;
};
}
// Property Decorator
function Prop(target: Object, propertyName: string) {
console.log(target);
console.log(propertyName);
let value: number;
const getter = () => {
console.log('Getting value...');
return value;
};
const setter = (newVal: number) => {
console.log('Setting value...');
value = newVal;
};
Object.defineProperty(target, propertyName, { get: getter, set: setter });
}
@Component({
id: 'Hello world! x Class Decorator'
})
export class TestClass {
static elementId: string;
@Prop
id!: number;
@MethodTest
printId(prefix: string = ''): string {
return prefix + this.id;
}
}
console.log(new TestClass().id);
console.log(new TestClass().printId('Shidqi!'));
// OBJECT
const person: {
name: string;
age: number;
hobbies: string[];
campus: {
name: string;
};
} = {
name: 'Nauval',
age: 23,
hobbies: ['Reading', 'Sport'],
campus: {
name: 'YAI',
},
};
console.log(person.campus.name);
// ARRAY
let nama: string[] = ['nauval', 'shidqi'];
let umur: number[] = [1, 2, 3, 4];
let detail: any[] = ['Nauval', 23, 'Jakarta', true];
let arrayOfObject: { nama: string; umur: number }[] = [
{
nama: 'Nauval',
umur: 23,
},
{
nama: 'Shidqi',
umur: 30,
},
];
for (let el of detail) {
console.log(el);
}
for (let obj of arrayOfObject) {
console.log(obj);
}
// TUPLE
// tuple sama seperti array,
// hanya saja length dan tipe data nya fixed
let tuples: [string, number, boolean];
tuples = ['Nauval', 24, false];
// ENUM
// untuk membuat sebuah label yang mudah untuk dibaca manusia
enum Role {
SUPERADMIN,
ADMIN,
USER,
}
// secara default nilainya SUPERADMIN = 0, ADMIN = 1, dst.
// tapi kita bisa definisikan sendiri, misal:
// enum Role2 {
// SUPERADMIN = 'SUPERADMIN',
// ADMIN = 'ADMIN',
// USER = 'USER',
// }
const personEnum = {
name: 'Nauval',
role: Role.ADMIN,
};
if (personEnum.role === Role.ADMIN) console.log('role is ADMIN');
// UNION (ATAU)
// LITERAL
// TYPE
type Combinable = number | string;
type ConversionDescriptor = 'asNumber' | 'asString';
function combine(
input1: Combinable,
input2: Combinable,
resultCoversion: ConversionDescriptor
) {
let result: number | string;
if (
(typeof input1 == 'number' && typeof input2 == 'number') ||
resultCoversion == 'asNumber'
) {
result = +input1 + +input2;
} else {
result = `${input1}${input2}`;
}
return result;
}
console.log(combine(10, 15, 'asNumber'));
console.log(combine('10', '15', 'asNumber'));
console.log(combine('Nauval', 'Shidqi', 'asString'));
type User = { name: string; age: number };
const u1: User = { name: 'Max', age: 30 }; // this works!
function getUserName(user: User): string {
return user.name;
}
console.log(getUserName(u1));
// Unknown
// kurang lebih sama seperti any
// any = paling fleksibel
// unknown = sangat dibatasi
// contoh
let x: unknown;
let y: string;
x = 12;
x = 'Nauval';
//y = x; // ini akan error karena unkwown tidak menjamin data tersebut string
// cara perbaikinya harus ada extra check:
if (typeof x === 'string') y = x;
// function with return something
function add(x: number, y: number): number {
return x + y;
}
console.log(add(2, 3));
// function without return anything
function printThis(word: string): void {
console.log(word);
}
printThis('Hello World');
// function as Types
let combineValues: (x: number, y: number) => number;
combineValues = add;
console.log(combineValues(10, 3));
// function with Callback
function addAndHandle(x: number, y: number, cb: (result: number) => void) {
const result = x + y;
cb(result);
}
addAndHandle(50, 30, (result) => {
if (result > 100) {
console.log('Lulus!');
} else {
console.log('Remedial :(');
}
});
// Class adalah ‘cetak biru’ atau ‘blueprint’ dari object.
// Class digunakan hanya untuk membuat kerangka dasar.
// Yang akan kita pakai nantinya adalah hasil cetakan dari class, yakni object.
export class User {
name: string;
constructor(name: string, public age: number) {
this.name = name;
}
setName(value: string): void {
this.name = value;
}
getName(): string {
return this.name;
}
}
console.log(typeof User);
// inheritance
class Admin extends User {
read: boolean = true;
write: boolean = true;
phoneNumber: string;
private _email: string = '';
static getRoleName: string = 'superadmin'; // static bisa langsung diakses
constructor(name: string, age: number, phoneNumber: string) {
super(name, age); // -> mewarisi constructor dari parent
this.phoneNumber = phoneNumber;
}
// static bisa langsung diakses tanpa instansiasi
static getNIK(): string {
return '78465782124';
}
getRole(): { [key: string]: boolean } {
return {
read: this.read,
write: this.write,
};
}
set email(email: string) {
if (email.length < 3) {
this._email = 'Error!';
} else {
this._email = email;
}
}
get email(): string {
return this._email;
}
}
// public: dapat diakses dialam maupun diluar class
// protected: hanya bisa diakses class itu sendiri dan turunannya
// private: hanya bisa diakses class itu sendiri
const admin = new Admin('Shidqi', 21, '087875789220');
admin.getName();
console.log('admin.getName()', admin.getName()); // -> Shidqi
admin.getRole();
console.log('admin.getRole()', admin.getRole()); // -> { read: true, write: true }
admin.email = 'admin@example.com';
console.log('admin.email', admin.email); // -> admin@example.com
console.log('Admin.getRoleName', Admin.getRoleName); // -> superadmin
console.log('Admin.getNIK', Admin.getNIK()); // -> 78465782124
// Abstact class
// abstract tidak dapat di instansiasi
// hanya dapat digunakan oleh class turunannya saja
abstract class Vehicle {
abstract wheels: number;
start(): string {
return 'Brumm brumm....';
}
}
class Car extends Vehicle {
wheels: number = 4;
}
const car = new Car();
console.log(car.wheels);
// const user: User = new User('Nauval', 25);
// Generics memungkinkan kita untuk membuat function atau data structure yang gak kaku sama satu tipe data aja,
// melainkan dengan tipe data apapun dia ayok-ayok aja: a.k.a terserah yang manggil.
// Tentunya bisa dibatasi dengan constraints
class List<T> {
data: T[];
constructor(...data: T[]) {
this.data = data;
}
add(element: T): void {
this.data.push(element);
}
getAll(): T[] {
return this.data;
}
}
const list = new List<number>(1, 3, 5, 7);
list.add(2);
console.log(list.getAll());
// Contoh 2
interface RemoteData<T> {
data: T;
status: 'IDLE' | 'FETCHING';
}
const createRemoteData = <T>(data: T): RemoteData<T> => ({
data,
status: 'IDLE',
});
interface User {
id: number;
name: string;
}
console.log(createRemoteData<string>('12345'));
console.log(
createRemoteData<User[]>([{ id: 1, name: 'Nauval' }])
);
// contoh 3 menggunakan constraint "extends"
const keys = <T extends { [keys: string]: any }>(obj: T) => Object.keys(obj);
console.log(keys({ name: 'Nauval', age: 23 }));
// Secara sederhana, Object Interface adalah sebuah ‘kontrak’ atau perjanjian implementasi method.
// Bagi class yang menggunakan object interface, class tersebut harus mengimplementasikanulang seluruh method
// yang ada di dalam interface. Dalam pemrograman objek,
// penyebutan object interface sering disingkan dengan ‘Interface’ saja.
interface Notebook {
name: string;
on(): string;
}
class Asus implements Notebook {
name: string;
constructor(name: string, public isGaming: boolean) {
this.name = name;
this.isGaming = isGaming;
}
on(): string {
return 'turning on...';
}
}
const asus = new Asus('A455LF', false);
console.log(asus.name);
console.log(asus.on());
// Intersection
// memungkinkan menggabungkan 2 tipe data
type Employee = {
name: string;
privileges: string[];
};
type Person = {
name: string;
age: number;
};
type elevatedEmployee = Employee & Person;
const employee: elevatedEmployee = {
name: 'Nauval',
privileges: ['admin'],
age: 23,
};
console.log(employee);
// type casting
// as untuk menandakan tipe data dari suatu variable
// ! untuk memastikan bahwa variable tidak pernah/akan null
// contoh versi 1
const username101 = document.querySelector('#username')! as HTMLInputElement;
// contoh versi 2
const username = document.querySelector('#username');
if (username) {
(username as HTMLInputElement).value = 'Nauval';
}
// Nullish Coalescing
// ?? untuk mengecek apakah data tidak bernilai undefined / null
// penjelasan contoh
// jika undefined / null, maka bernilai default_value
// jika tidak akan mencetak fullName (karena string kosong != undefined / null)
const fullname = '';
const dataStudent = fullname ?? 'DEFAULT_VALUE';
console.log(dataStudent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment