Index signature
Trong TypeScript, có trường hợp muốn chỉ định type của property mà không chỉ định tên field của object. Lúc này có thể sử dụng index signature. Ví dụ, object có tất cả property là type number được type annotation như sau.
tsletobj : {[K : string]: number;};
tsletobj : {[K : string]: number;};
Phần biểu thị tên field là [K: string]. K ở đây là type variable. Có thể đặt tên type variable tùy ý. Thường dùng K hoặc key. Phần string biểu thị type của tên field. Type của tên field trong index signature chỉ có thể chỉ định string, number, symbol.
Với object có index signature, có thể gán property mà tên field chưa được định nghĩa. Ví dụ, với index signature { [K: string]: number }, nếu value là type number, có thể gán vào các field chưa định nghĩa như a, b.
tsletobj : {[K : string]: number;};obj = {a : 1,b : 2 }; // OKobj .c = 4; // OKobj ["d"] = 5; // OK
tsletobj : {[K : string]: number;};obj = {a : 1,b : 2 }; // OKobj .c = 4; // OKobj ["d"] = 5; // OK
Khi bật compiler option noUncheckedIndexedAccess, với index signature, type của property tự động trở thành union type của type chỉ định và undefined. Điều này để biểu thị chính xác rằng khi property không tồn tại, giá trị sẽ là undefined.
tsconstobj : { [K : string]: number } = {a : 1 };constb : number | undefined =obj .b ;console .log (b );
tsconstobj : { [K : string]: number } = {a : 1 };constb : number | undefined =obj .b ;console .log (b );
📄️ noUncheckedIndexedAccess
Bắt buộc check undefined khi tham chiếu property của index type hoặc phần tử array
Index signature sử dụng Record<K, T>
Index signature cũng có thể biểu thị bằng utility type Record<K, T>. Hai type annotation sau có cùng ý nghĩa.
tsletobj1 : { [K : string]: number };letobj2 :Record <string, number>;
tsletobj1 : { [K : string]: number };letobj2 :Record <string, number>;
📄️ Record<Keys, Type>
Tạo object type từ key-value
Thông tin liên quan
📄️ Mapped Types
Với index type, bạn có thể tự do thiết lập bất kỳ key nào khi gán giá trị, nhưng khi truy cập phải kiểm tra undefined mỗi lần. Nếu format input đã được xác định rõ ràng, bạn có thể cân nhắc sử dụng Mapped Types.