Khắc phục lỗi 'Neither Type Sufficiently Overlaps' trong TypeScript

intermediate🔵 TypeScript2026-04-29| TypeScript 3.0+ / Node.js / VS Code

Error Message

Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
#typescript#ép-kiểu#sai-lệch-kiểu#unknown#chuyển-đổi-dữ-liệu

Tình huống lỗi

Lỗi này thường xảy ra khi bạn cố gắng ép một biến sang một kiểu dữ liệu mà nó không thể thuộc về. TypeScript kiểm tra sự 'chồng lấp' (overlap)—nghĩa là liệu hai kiểu này có bao giờ có điểm chung không? Nếu câu trả lời là 'không,' trình biên dịch sẽ chặn việc ép kiểu để bảo vệ bạn khỏi những lỗi runtime nghiêm trọng.

Hãy xem xét một sai lầm phổ biến khi lập trình viên cố gắng ép kiểu một chuỗi từ API trực tiếp sang số:

const priceInput = "49.99";

// Điều này sẽ gây ra lỗi:
// Conversion of type 'string' to type 'number' may be a mistake...
const price = priceInput as number;

Phân tích: Tại sao TypeScript lại chặn bạn

TypeScript chỉ cho phép ép kiểu (từ khóa as) nếu kiểu này là kiểu con của kiểu kia. Hãy tưởng tượng nó như một cây gia phả. Bạn có thể ép một HTMLElement chung sang một HTMLButtonElement cụ thể vì nút bấm là một loại phần tử. Chúng có chung các thuộc tính.

Các kiểu dữ liệu nguyên thủy như stringnumber thì khác. Chúng nằm trên những nhánh hoàn toàn riêng biệt. Một chuỗi như "123" không bao giờ thực sự là con số 123 trong mắt trình biên dịch. Ép kiểu as number cho một chuỗi thực chất là "nói dối" runtime. Điều này dẫn đến kết quả NaN hoặc làm ứng dụng bị crash khi thực hiện các phép toán.

Cách sửa nhanh: Ép kiểu kép (Double Casting)

Đôi khi bạn phải làm việc với dữ liệu lộn xộn từ bên thứ ba và bạn chắc chắn 100% về kết quả. Trong những trường hợp hiếm hoi đó, bạn có thể bỏ qua bước kiểm tra an toàn bằng cách sử dụng một kiểu trung gian là unknown. Thông báo lỗi thậm chí còn gợi ý giải pháp này.

const priceInput = "49.99";

// Bước 1: Ép kiểu sang unknown (kiểu dữ liệu cao nhất)
// Bước 2: Ép kiểu sang kiểu dữ liệu đích
const price = (priceInput as unknown) as number;

Lưu ý: Cách này giúp xóa dấu gạch dưới màu đỏ, nhưng nó không làm thay đổi dữ liệu. Ở runtime, price vẫn là chuỗi "49.99". Nếu bạn gọi price.toFixed(2), ứng dụng của bạn sẽ bị crash vì toFixed là phương thức của kiểu số, không phải kiểu chuỗi.

Cách sửa triệt để: Chuyển đổi dữ liệu thực tế

Phần lớn thời gian, thứ bạn cần không phải là ép kiểu (cast) mà là chuyển đổi (conversion). Ép kiểu là yêu cầu trình biên dịch "nhắm mắt làm ngơ". Chuyển đổi thực sự thay đổi giá trị bên dưới sang định dạng chính xác.

Chuyển đổi Chuỗi sang Số

Hãy sử dụng các phương thức JavaScript tiêu chuẩn. Chúng an toàn và dễ đọc hơn:

const priceInput = "49.99";

// Lựa chọn A: Hàm khởi tạo Number (Tốt nhất để chuyển đổi nghiêm ngặt)
const price = Number(priceInput); 

// Lựa chọn B: parseFloat (Tuyệt vời để trích xuất số thập phân từ chuỗi lộn xộn)
const priceFloat = parseFloat(priceInput);

Sửa lỗi không tương thích giữa các Đối tượng

Các hàm ánh xạ (mapping functions) là "người bạn thân" nhất khi xử lý các interface không khớp nhau. Nếu API trả về ID kiểu chuỗi nhưng giao diện của bạn cần kiểu số, đừng cố ép kiểu. Hãy ánh xạ nó:

interface UserResponse {
  user_id: string; // ví dụ: "101"
  user_name: string;
}

interface AppUser {
  id: number; // ví dụ: 101
  name: string;
}

const rawData = { user_id: "101", user_name: "Alice" } as UserResponse;

// Ánh xạ dữ liệu thủ công để đảm bảo các kiểu dữ liệu khớp nhau
const user: AppUser = {
  id: parseInt(rawData.user_id, 10),
  name: rawData.user_name
};

Xử lý đối tượng "không đầy đủ" trong Unit Test

Lỗi này thường xuất hiện khi viết unit test. Bạn có thể chỉ muốn mock một vài trường của một interface khổng lồ. Nếu bạn cung cấp một đối tượng quá nhỏ, TypeScript sẽ phàn nàn rằng các kiểu dữ liệu không chồng lấp lên nhau.

Sử dụng Partial<T> thường là cách sửa sạch sẽ nhất. Nó báo cho TypeScript biết rằng bạn chỉ định cung cấp một số thuộc tính, giúp các kiểu dữ liệu 'chồng lấp' trở lại mà không cần dùng đến việc ép kiểu không an toàn.

Danh sách kiểm tra xác minh

Trước khi triển khai code, hãy xác minh bản sửa lỗi bằng ba bước sau:

  • Xác minh kiểu dữ liệu lúc Runtime: Thêm console.log(typeof price). Nó phải in ra "number", chứ không phải "string".
  • Thử một phép toán: Cộng thêm 10 vào kết quả. Nếu "49.99" + 10 bằng "49.9910", việc ép kiểu của bạn 'có vẻ chạy' nhưng logic đã sai. Nếu nó bằng 59.99, bạn đã thành công.
  • Kiểm tra trình biên dịch: Chạy tsc --noEmit từ terminal của bạn. Đảm bảo lỗi đã biến mất hoàn toàn.

Related Error Notes