Namespace berguna untuk melakukan grouping component dalam scope tersendiri, lebih sering disebut internal modular.
Berikut format untuk menggunakan namespace:
namespace Nama.Namespace{
//code goes here
}
namespace namaNamespace{
//code goes here
}
Anda bisa menggunakan format hieararki dengan menggunakan tanda dot (.) seperti diatas.
Dalam satu file javascript atau typescript, diperbolehkan untuk memiliki dua atau lebih namespace yang sama atau berbeda. Untuk jelasnya lihat code dibawah:
namespace Nama.Namespace1{
//code goes here
}
namespace Nama.Namespace1{
//code2 goes here
}
namespace Nama.Namespace2{
//code3 goes here
}
Pembuatan namespace seperti adalah valid. Mari kita praktekan dengan contoh code:
//contoh ini akan error
namespace TodoApp.Model{
interface Todo{
name: string;
state: TodoState;
}
enum TodoState{
New = 0,
Active,
Complete,
Deleted
}
}
namespace DataAccess{
interface ITodoService{
add(todo: Todo): Todo;
delete(todoId: number): void;
getAll(): Todo[];
getById(todoId: number): Todo;
}
}
Jika Anda coba masukan code diatas, maka TypeScript akan menampilkan error, karena namespace DataAccces berusaha mengakses interface Todo yang tidak ada dalam scope bersangkutan.
Perhatikan, namespace TodoApp.Model pertama tetap akan berisi error, walaupun deklarasi enum TodoState yang digunakan menggunakan namespace yang sama.
namespace TodoApp.Model{
interface Todo{
name: string;
state: TodoState;
}
}
namespace TodoApp.Model{
enum TodoState{
New = 0,
Active,
Complete,
Deleted
}
}
namespace DataAccess{
interface ITodoService{
add(todo: Todo): Todo;
delete(todoId: number): void;
getAll(): Todo[];
getById(todoId: number): Todo;
}
}
Agar suatu modul atau type dapat digunakan oleh namespace lainnya perlu diexpose dengan keyword export.
Hal diatas akan menyelesaikan error untuk namespace yang sama. Namun untuk namespace yang berbeda harus diperlukan proses import atau dengan menggunakan full namespace. Untuk jelasnya lihat contoh dibawah:
//menggunakan pendekatan full namespace
namespace DataAccess{
export interface ITodoService{
add(todo: TodoApp.Model.Todo): TodoApp.Model.Todo;
delete(todoId: number): void;
getAll(): TodoApp.Model.Todo[];
getById(todoId: number): TodoApp.Model.Todo;
}
}
//menggunakan import
namespace DataAccess{
import Todo = TodoApp.Model.Todo;
export interface ITodoService{
add(todo: Todo): Todo;
delete(todoId: number): void;
getAll(): Todo[];
getById(todoId: number): Todo;
}
}
Kedua cara pendekatan diatas valid, tidak ada aturan baku mana yang lebih disarankan. Umumnya digunakan pendekatan import jika namesapce panjang atau namespace digunakan lebih dari satu kali.
Jika Anda perhatikan hasil kompilasi TypeScript, code yang digenerate adalah berupa pattern IIFE (Immediately Invoked Function Expression) yang berguna untuk encapsulate code.
Topik tidak akan dibahas disini, karena tutorial ini lebih ke sisi TypeScript.
var TodoApp;
(function (TodoApp) {
var Model;
(function (Model) {
let TodoState;
(function (TodoState) {
TodoState[TodoState["New"] = 0] = "New";
TodoState[TodoState["Active"] = 1] = "Active";
TodoState[TodoState["Complete"] = 2] = "Complete";
TodoState[TodoState["Deleted"] = 3] = "Deleted";
})(TodoState = Model.TodoState || (Model.TodoState = {}));
})(Model = TodoApp.Model || (TodoApp.Model = {}));
})(TodoApp || (TodoApp = {}));
File Terpisah
Jika Anda menggunakan file terpisah untuk namespace berbeda, gunakan tag <reference path>.
Contoh, isi code a.ts akan berisi namespace TodoApp.Model
namespace TodoApp.Model{
export interface Todo{
name: string;
state: TodoState;
}
}
namespace TodoApp.Model{
export enum TodoState{
New = 0,
Active,
Complete,
Deleted
}
}
Sementara, isi code b.ts akan berisi namespace TodoApp.DataAcces. Maka harus ditambahkan <reference path>.
/// <reference path="a.ts" />
namespace DataAccess{
import Todo = TodoApp.Model.Todo;
export interface ITodoService{
add(todo: Todo): Todo;
delete(todoId: number): void;
getAll(): Todo[];
getById(todoId: number): Todo;
}
}
Saat kompilasi, harus didefinisikan seperti dibawah:
tsc a.ts b.ts
Atau Anda dapat menggunakan tsconfig.js dengan menggunakan config files atau include.
{
"compilerOptions": {
"target" : "es5"
},
"files": ["app.ts", "dataAccses.ts"]
}
Jika menggunakan include, Anda bisa buat folder untuk source TypeScript file.
{
"compilerOptions": {
"target" : "es5"
},
//"files": ["app.ts", "dataAccess.ts"]
"include" : ["*.ts"]
}