Skip to main content

Strings & Functions

Strings​

Dùng double quotes "" cho string​

// ❌ Tránh
const name = 'Capt. Janeway';

// ✅ Tốt
const name = "Capt. Janeway";

Chuỗi dài: dùng template string, tránh nối nhiều dòng bằng +​

// ❌ Tránh
const errorMessage =
"This is a " +
"super long error that was thrown because of Batman. " +
"When you stop to think about it, you would get nowhere fast.";

// ✅ Tốt
const errorMessage = `This is a super long error that was thrown because of Batman.
When you stop to think about it, you would get nowhere fast.`;

Tạo chuỗi động: dùng template string thay vì nối​

// ❌ Tránh
function sayHi(name: string): string {
return "How are you, " + name + "?";
}

// ✅ Tốt
function sayHi(name: string): string {
return `How are you, ${name}?`;
}

Không dùng eval() trên chuỗi — dễ lỗ hổng bảo mật​

// ❌ Tránh: không bao giờ dùng
const code = "alert('xss')";
eval(code);

// ✅ Tốt: dùng JSON.parse cho JSON, hoặc logic an toàn khác
const data = JSON.parse(jsonString) as MyType;

Functions​

Ưu tiên named function expression thay vì function declaration​

Function declaration bị hoisting, dễ tham chiếu trước khi định nghĩa, khó đọc. Nên đặt tên cho function expression.

// ❌ Tránh
function foo(): void {}

// ✅ Tốt
const short = function longUniqueMoreDescriptiveLexicalFoo(): void {};

IIFE: bọc trong ngoặc tròn​

// ❌ Tránh: không bọc, có thể bị ASI nhầm
function () {
console.log("Welcome.");
}();

// ✅ Tốt
(function (): void {
console.log("Welcome.");
})();

Không khai báo function trong block không phải function (if, while, …)​

Gán function vào biến rồi gán trong block.

// ❌ Tránh: hành vi khác nhau giữa các runtime
if (currentUser) {
function test(): void {
console.log("Yup.");
}
}

// ✅ Tốt
let test: (() => void) | undefined;
if (currentUser) {
test = (): void => {
console.log("Yup.");
};
}

Không đặt tên tham số là arguments​

Sẽ che arguments của function.

// ❌ Tránh: arguments bên trong là tham số, không phải object arguments
function foo(name: string, options: object, arguments: unknown): void {
console.log(arguments); // là tham số thứ 3, không phải danh sách đối số
}

// ✅ Tốt
function foo(name: string, options: object, args: unknown): void {
console.log(args);
}

Dùng rest ... thay vì arguments​

// ❌ Tránh: arguments là array-like, không có .map/.filter
function concatenateAll(): string {
const args = Array.prototype.slice.call(arguments);
return args.join("");
}

// ✅ Tốt
function concatenateAll(...args: string[]): string {
return args.join("");
}

Dùng default parameter thay vì mutate tham số​

type RequestOptions = { timeout?: number };

// ❌ Tránh: mutate tham số
function handleThings(opts: RequestOptions): void {
if (!opts) opts = {};
opts.timeout = opts.timeout ?? 1000;
}

// ✅ Tốt
function handleThings(opts: RequestOptions = {}): void {
const timeout = opts.timeout ?? 1000;
}

Default parameter đặt cuối; không side effect trong default​

// ❌ Tránh: default ở giữa, tham số sau khó truyền
function handleThings(opts: RequestOptions = {}, name: string): void {}

// ✅ Tốt
function handleThings(name: string, opts: RequestOptions = {}): void {}

// ❌ Tránh: side effect trong default
let b = 1;
function count(a: number = b++): void {
console.log(a);
}
count(); // 1
count(); // 2 — khó đoán

// ✅ Tốt
function count(a: number = 0): void {
console.log(a);
}

Không mutate hoặc reassign tham số​

// ❌ Tránh
function f1(obj: { key: number }): void {
obj.key = 1;
}
function f2(a: number): void {
a = 1;
}

// ✅ Tốt
function f1(obj: { key: number }): void {
const newKey = obj.key !== undefined ? obj.key : 1;
// tạo object mới hoặc return thay vì mutate obj
}
function f2(a: number): number {
const b = a || 1;
return b;
}

Gọi hàm variadic: dùng spread ...​

const x = [1, 2, 3, 4, 5];

// ❌ Tránh
console.log.apply(console, x);

// ✅ Tốt
console.log(...x);

// ✅ Tốt: với new
const date = new Date(...[2024, 2, 15]);

Arrow Functions​

Callback vô danh: dùng arrow function​

// ❌ Tránh
[1, 2, 3].map(function (x: number) {
const y = x + 1;
return x * y;
});

// ✅ Tốt
[1, 2, 3].map((x: number) => {
const y = x + 1;
return x * y;
});

Body chỉ một biểu thức không side effect: bỏ ngoặc và dùng implicit return​

// ❌ Tránh: không return, trả về undefined
[1, 2, 3].map((number: number) => {
`A string containing the ${number}.`;
});

// ✅ Tốt
[1, 2, 3].map((number: number) => `A string containing the ${number}.`);

// ✅ Tốt: nhiều dòng thì bọc ngoặc
[1, 2, 3].map((number: number) => ({
value: number,
label: `Item ${number}`,
}));

Luôn dùng ngoặc quanh tham số​

// ❌ Tránh: thêm/xóa tham số dễ gây diff rối
[1, 2, 3].map((x) => x * x);

// ✅ Tốt
[1, 2, 3].map((x) => x * x);

// ✅ Tốt: một tham số cũng nên có ngoặc
[1, 2, 3].map((number) => number + 1);

Tránh nhầm => với <= / >=​

type Item = { height: number; largeSize: number; smallSize: number };

// ❌ Tránh: dễ đọc nhầm
const itemHeight = (item: Item) =>
item.height <= 256 ? item.largeSize : item.smallSize;

// ✅ Tốt: bọc biểu thức return trong ngoặc
const itemHeight = (item: Item): number =>
item.height <= 256 ? item.largeSize : item.smallSize;

// ✅ Tốt: dùng block rõ ràng
const itemHeight = (item: Item): number => {
const { height, largeSize, smallSize } = item;
return height <= 256 ? largeSize : smallSize;
};