TypeScript Types & Interfaces
Types (kiểu dữ liệu) và Interfaces là hai tính năng cốt lõi của TypeScript giúp định nghĩa cấu trúc của dữ liệu. Chúng giúp bắt lỗi sớm khi code và cải thiện chất lượng code.
Kiểu dữ liệu cơ bản (Basic Types)
TypeScript hỗ trợ nhiều kiểu dữ liệu cơ bản:
Boolean
let isDone: boolean = false;
Number
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
String
let color: string = "blue";
let fullName: string = `Bob Smith`;
let sentence: string = `Hello, my name is ${fullName}`;
Array
let list: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3]; // Generic array type
Tuple
let x: [string, number];
x = ["hello", 10]; // OK
x = [10, "hello"]; // Error
Enum
enum Color {Red, Green, Blue}
let c: Color = Color.Green; // 1
// Có thể gán giá trị cho enum
enum Status {
Active = 1,
Inactive = 2,
Pending = 3
}
Any
let notSure: any = 4;
notSure = "maybe a string";
notSure = false; // Cũng OK
Void
function warnUser(): void {
console.log("This is a warning message");
}
Null and Undefined
let u: undefined = undefined;
let n: null = null;
Never
// Function throwing an error
function error(message: string): never {
throw new Error(message);
}
// Function with infinite loop
function infiniteLoop(): never {
while (true) {}
}
Object
let obj: object = {};
Type Assertions (Khẳng định kiểu)
Type assertions giúp bạn nói với compiler rằng bạn biết rõ kiểu dữ liệu của biến:
// Cách 1: angle-bracket syntax
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// Cách 2: as syntax (thường dùng với JSX)
let strLength2: number = (someValue as string).length;
Interfaces
Interfaces định nghĩa “hình dáng” của một object, chỉ ra các thuộc tính và phương thức nào mà một object cần có.
Interface cơ bản
interface Person {
firstName: string;
lastName: string;
age: number;
}
function greet(person: Person) {
return `Hello, ${person.firstName} ${person.lastName}`;
}
const user = { firstName: "John", lastName: "Doe", age: 30 };
console.log(greet(user)); // Output: Hello, John Doe
Optional Properties (Thuộc tính tùy chọn)
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig): { color: string; area: number } {
const newSquare = { color: "white", area: 100 };
if (config.color) {
newSquare.color = config.color;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
Readonly Properties (Thuộc tính chỉ đọc)
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // Error: Cannot assign to 'x' because it is a read-only property
Function Types
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(src, sub) {
return src.search(sub) > -1;
};
Indexable Types
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0]; // "Bob"
Class Types
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}
}
Extending Interfaces (Kế thừa Interface)
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
Type Aliases
Type aliases tạo tên mới cho một kiểu dữ liệu:
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n;
} else {
return n();
}
}
Union và Intersection Types
Union Types (Kiểu hợp)
// Biến có thể nhận một trong các kiểu được liệt kê
function padLeft(value: string, padding: string | number) {
// ...
}
Intersection Types (Kiểu giao)
// Kết hợp nhiều types lại với nhau
interface ErrorHandling {
success: boolean;
error?: { message: string };
}
interface ArtworksData {
artworks: { title: string }[];
}
type ArtworksResponse = ArtworksData & ErrorHandling;
Generic Types
Generic types cho phép bạn tạo các components/functions có thể làm việc với nhiều kiểu dữ liệu khác nhau:
// Generic function
function identity<T>(arg: T): T {
return arg;
}
// Gọi với kiểu dữ liệu tường minh
let output = identity<string>("myString");
// Hoặc để compiler tự suy luận kiểu
let output2 = identity("myString");
Kết luận
TypeScript Types và Interfaces là những công cụ mạnh mẽ giúp nâng cao sự rõ ràng và an toàn cho code JavaScript. Việc hiểu và áp dụng chúng đúng cách sẽ giúp ứng dụng của bạn ổn định và dễ bảo trì hơn.