Typescript satisfies biến kiểu boolean thành literal. Điều này có bình thường không?
Trong khi các loại khác giữ nguyên, kiểu 'boolean' trở thành giá trị literal 'false' sau khi thỏa mãn "TypesSamples"
interface TypesSamples {
str: string;
int: number;
arr: Array<any>;
bool: boolean;
}
const types = {
str: "a",
int: 0,
arr: [1],
bool: false,
} satisfies TypesSamples; // satisfies here
types.str = "abc";
types.int = 1000;
types.arr = [2, 3];
types.bool = true; // Type 'true' is not assignable to type 'false'.
Điều này có phải là hành vi mong đợi hay là một vấn đề?
Câu trả lời #1
Đây là hành vi mong đợi, như được mô tả trong microsoft/TypeScript#55189. Toán tử satisfies như đã được triển khai trong microsoft/TypeScript#46827, cung cấp một kiểu ngữ cảnh, một số khi có thể thay đổi hành vi suy diễn kiểu. Lý do tại sao điều này là đặc thù cho boolean chứ không phải, ví dụ, string, là vì boolean thực ra chỉ là một cách viết tắt cho kiểu hợp true | false. Mặc dù nó hiển thị như một kiểu đơn, thực ra nó là một kiểu hợp. Bạn có thể xác minh điều này bằng cách tự định nghĩa một kiểu là true | false và thấy rằng nó hiển thị như boolean:
type B = true | false;
// ^? type B = boolean
Vì vậy, true khi được đánh giá theo ngữ cảnh bởi true | false vẫn giữ là true, trái ngược với "a" khi được đánh giá theo ngữ cảnh bởi string trong một biểu thức satisfies, vẫn được mở rộng thành string như thường lệ.
Đó là mức độ gần nhất mà tôi có thể đưa ra một câu trả lời "chính thức", dù sao đi nữa, dựa trên các chi tiết của microsoft/TypeScript#55189. Thật không may khi yêu cầu kéo trong microsoft/TypeScript#46827 không đi vào bất kỳ chi tiết nào trong mô tả về cách thức chính xác mà nó được cho là hoạt động. Có những phần khác của TypeScript mà việc cung cấp ngữ cảnh string/number cho một literal sẽ dẫn đến một kiểu literal, và điều đó không xảy ra ở đây, ngoại trừ boolean. Kiểu boolean khác với các kiểu khác bởi nó là một hợp nhất rõ ràng, vì vậy không quá ngạc nhiên khi hành vi của nó khác nhau, nhưng liệu điều này có thực sự là chủ ý hay chỉ là một hiện tượng của việc triển khai thì tôi không thể nói chắc chắn được.
Liên kết Playground đến mã
