Gặp gỡ type-tune! 🦀 Cho các TypeScript type một ngôi nhà tốt hơn! 😸
Hoi hoi! 👋
Mình là @nyaomaru, một frontend engineer thực ra lại bị dị ứng với cua! 🙀🦀
Hôm nay mình có thêm một tin rất vui!
Mình vừa phát hành một công cụ open source mới tên là type-tune! 🦀🎉
https://github.com/necoz-oss/type-tune
https://type-tune-docs.vercel.app/
Đây là một công cụ CLI nhỏ viết bằng Rust 🦀, giúp bạn tìm các TypeScript type đang được chia sẻ và chuyển chúng đến vị trí phù hợp hơn.
Scan. Review. Move. Validate.
Nghe đơn giản nhỉ?
Đúng vậy, đó chính là ý tưởng! 😸
🐈 type-tune là gì?
Nếu từng làm việc với một dự án TypeScript lớn, có lẽ bạn đã sử dụng những công cụ như Knip.
Knip thật tuyệt! 🎉
Nó giúp tìm những file, export và dependency không còn được sử dụng, nhờ đó việc dọn dẹp codebase dễ dàng hơn.
Nhưng có một vấn đề khác mà mình vẫn luôn nghĩ tới:
Còn những type vẫn đang được sử dụng nhưng chưa được tổ chức hợp lý thì sao?
TypeScript type có khả năng tái sử dụng rất cao.
Một type khai báo trong một component có thể dần được sử dụng ở component khác, module API, hoặc thậm chí cả một feature.
Nhưng trên thực tế, không phải lúc nào chúng ta cũng chú ý đến việc duy trì tổ chức của các type declaration.
Ví dụ, hãy tưởng tượng có đoạn code này:
// src/features/order/OrderPage.tsx
export type OrderSummary = {
id: string;
total: number;
};
Ban đầu, OrderSummary có thể chỉ được dùng trong OrderPage.
Nhưng khi feature phát triển, các file khác bắt đầu import nó.
Đôi khi developer còn khai báo lại những type tương tự vì không biết rằng đã có một type có thể tái sử dụng.
Cuối cùng, dự án có thể xuất hiện:
- Type nằm rải rác trong component và utility.
- Nhiều khai báo type tương tự bị lặp lại trong cùng một feature.
- Type dùng chung lại nằm trong file không còn phù hợp.
- Import khiến việc refactor phức tạp không cần thiết.
Mọi thứ vẫn chạy!
Nhưng có dễ maintain không?
Hmm, không hẳn. 😹
Đó là lúc type-tune xuất hiện!
type-tune tìm các exported type và interface đang được nhiều file sử dụng rồi giúp chuyển chúng đến vị trí thích hợp hơn.
Nó cũng có thể cập nhật những import được hỗ trợ và giữ lại các compatibility re-export, nên bạn không cần tự đi tìm và sửa từng reference trong dự án.

Khác với Knip tập trung vào code không còn dùng, type-tune tập trung vào tổ chức những type thực sự đang được sử dụng.
Hai công cụ bổ sung cho nhau!
Một công cụ giúp xóa những gì không cần nữa. Công cụ kia giúp sắp xếp những gì vẫn cần. 😸
💡 Vì sao mình tạo ra nó?
Ý tưởng này xuất phát từ chính trải nghiệm của mình.
Mình đang refactor một codebase production có hơn 300.000 dòng code.
Và có một điều liên tục khiến mình băn khoăn:
Chúng ta chưa tận dụng tốt những type đã có sẵn.
Ngay trong cùng một feature, những type lẽ ra có thể dùng chung đôi khi vẫn được khai báo riêng.
Một số type dần trở thành dependency dùng chung, nhưng vẫn nằm ở vị trí nơi chúng được tạo ra ban đầu.
Codebase càng phát triển, việc maintain các mối quan hệ này càng khó khăn.
Và mình còn nhận ra một điều khác.
🤖 Type còn có giá trị hơn trong thời đại AI
Gần đây mình sử dụng AI-assisted development khá nhiều.
Qua trải nghiệm đó, mình càng trân trọng TypeScript type system hơn.
Type không chỉ dùng để bắt lỗi.
Chúng cũng có thể trở thành những guardrail hữu ích cho AI coding agent. 🛤️
Type được định nghĩa rõ ràng giúp truyền đạt cấu trúc ứng dụng, quan hệ giữa dữ liệu và các contract mà code phải tuân theo.
Theo trải nghiệm của mình, làm rõ các contract này là một phần quan trọng của workflow phát triển với AI hiệu quả.
Nhưng có một vấn đề!
Nếu type bị trùng lặp, phân tán hoặc không được maintain tốt, chúng ta đang lãng phí thông tin đó.
Vậy nên mình bắt đầu tự hỏi:
Tại sao không có một công cụ giúp chúng ta tự động duy trì cấu trúc của các type?
Mình tìm thử nhưng không thấy công cụ nào giải quyết đúng vấn đề mình đang nghĩ đến.
Vậy là...
Mình quyết định tự làm một cái! 🦀🎉
YAY!!!
🚀 Cách dùng type-tune
Bắt đầu khá đơn giản!
📦 Cài đặt
Bạn có thể cài type-tune bằng npm:
npm install -D type-tune
Hoặc bằng pnpm (món khoái khẩu của mình 😸):
pnpm add -D type-tune
Bạn cũng có thể thử ngay mà không cần cài vào dự án:
npx type-tune scan --project tsconfig.json
Package npm yêu cầu Node.js v22 trở lên và chạy native Rust binary phù hợp với từng platform.
Vì type-tune được viết bằng Rust, bạn cũng có thể build và cài trực tiếp từ GitHub bằng Cargo! 📦
cargo install --git https://github.com/necoz-oss/type-tune --tag v1.0.0 type-tune
Source Rust yêu cầu Rust 1.99 trở lên.
🔍 Bước 1. Tìm các type dùng chung
Đầu tiên, scan dự án TypeScript:
npx type-tune scan --project tsconfig.json
type-tune phân tích dự án và tìm các candidate có thể di chuyển.
Mặc định, nó tìm exported type và interface được ít nhất hai file khác tham chiếu.
Đừng lo!
Scan không thay đổi code của bạn. 😸
📋 Bước 2. Tạo kế hoạch refactor
Tiếp theo, tạo một plan:
npx type-tune plan \
--project tsconfig.json \
--out .type-tune/plan.json \
--markdown .type-tune/plan.md
Lệnh này tạo một JSON plan và một file Markdown để bạn review.
Bạn có thể xem những type được phát hiện, nơi chúng đang được khai báo và nơi có thể chuyển đến.
🐈 Bước 3. Review các thay đổi
Đây là một phần rất quan trọng!
type-tune không tự quyết định chuyển tất cả mọi thứ.
Mỗi candidate ban đầu đều có trạng thái ignore.
Bạn có thể review plan và chọn declaration nào thực sự cần di chuyển.
npx type-tune review \
--markdown .type-tune/plan.md
Bạn cũng có thể tự chỉnh sửa Markdown plan.
Mình muốn công cụ tự động hóa những công việc tẻ nhạt, nhưng quyết định kiến trúc vẫn thuộc về developer.
Automation hữu ích. Nhưng quyền kiểm soát cũng quan trọng! 😸
🦀 Bước 4. Áp dụng thay đổi
Sau khi review plan, bạn có thể xem trước kết quả refactor:
npx type-tune apply \
--plan .type-tune/plan.json \
--markdown .type-tune/plan.md \
--dry-run
type-tune thực hiện các rewrite được hỗ trợ, validate bằng TypeScript và khôi phục các file đã thay đổi sau một lần dry-run bình thường.
Khi bạn hài lòng với plan, hãy chạy:
npx type-tune apply \
--plan .type-tune/plan.json \
--markdown .type-tune/plan.md
Xong! 🎉
Với những transformation được hỗ trợ, type-tune sẽ di chuyển declaration, cập nhật type import và validate kết quả bằng TypeScript compiler.
Tất nhiên, bạn vẫn nên review Git diff và chạy các bước kiểm tra của chính dự án.
✨ Chỉ muốn chuyển một type thôi?
Còn có một command extract trực tiếp nữa!
npx type-tune extract OrderSummary \
--from src/features/order/OrderPage.tsx \
--to src/features/order/types/order.ts \
--project tsconfig.json \
--dry-run
Khá tiện đúng không? 😸
🐈 Cùng xây dựng type-tune nhé!
Mình phát hành type-tune dưới Necoz vì muốn cùng các developer khác phát triển nó! 😸💚
Và lần này là với Rust! 🦀
Mình tin open source sẽ thú vị hơn khi chúng ta chia sẻ ý tưởng, học hỏi lẫn nhau và cùng xây dựng sản phẩm.
Nếu bạn có ý tưởng, gợi ý hoặc muốn đóng góp, mình rất muốn được nghe!
Cùng giúp type-tune phát triển nhé! 🐈
🌱 Mới chỉ là khởi đầu!
Đây là bản phát hành public đầu tiên, v1!
Hiện tại, type-tune tập trung vào TypeScript type alias và interface được export trong file .ts và .tsx.
Nó chưa tự động merge các type definition trùng lặp, cũng chưa xử lý được mọi kiểu TypeScript refactoring.
Nhưng mình nghĩ đây là bước đầu tiên hữu ích để việc maintain type dễ dàng hơn.
Và vẫn còn rất nhiều điều có thể cải thiện!
Mình rất muốn nghe về những khó khăn bạn gặp phải khi maintain type trong các dự án TypeScript lớn.
Có thể bạn cũng từng gặp đúng những vấn đề này!
Hoặc có thể bạn đã tìm ra một cách tiếp cận hoàn toàn khác.
Dù thế nào, mình cũng rất muốn học hỏi từ kinh nghiệm của bạn! 💚
💚 Ghé xem dự án nhé!
type-tune là open source và đã có trên GitHub!
https://github.com/necoz-oss/type-tune
Nếu thấy thú vị, hãy cân nhắc tặng một ⭐ trên GitHub nhé! 😸
Nếu bạn có ý tưởng, gợi ý hoặc tìm thấy bug, cứ thoải mái mở issue hoặc đóng góp!
Mỗi feedback đều giúp những dự án nhỏ này tốt hơn.
🦀 Bài tiếp theo
À, còn một điều nữa!
Có lẽ bạn đang thắc mắc:
Tại sao mình lại chọn Rust thay vì TypeScript để làm một công cụ refactor TypeScript? Chẳng phải nyaomaru rất mê TypeScript sao? 🤔
Thật ra đó là một câu chuyện khá thú vị!
Trong bài tiếp theo, mình sẽ chia sẻ lý do quyết định như vậy, những gì mình học được khi xây dựng nó và trải nghiệm sử dụng Rust!
Đón xem nhé! 🦀
Cảm ơn đã đọc, chúc bạn code vui vẻ! 😸🙌
💚 Tham gia cộng đồng Necoz!
À, và một điều nữa! 😸
Chúng mình cũng có cộng đồng Necoz trên DEV! 🎉
Ai cũng được chào đón, dù bạn là developer, người viết bài hay chỉ đơn giản là tò mò!
Muốn tham gia? Hãy để lại comment bên dưới, mình sẽ gửi lời mời! 💌
Không áp lực, không ràng buộc. Cứ ghé chơi cùng chúng mình nhé! 🐈
Small. Simple. Useful. Built Together! 💚
All Rights Reserved