Có một số tình huống sẽ cung cấp cho bạn lỗi đặc biệt này. Trong trường hợp của OP, có một giá trị được xác định rõ ràng là một chuỗi . Vì vậy, tôi phải giả định rằng có thể điều này xuất phát từ một danh sách thả xuống, hoặc dịch vụ web hoặc chuỗi JSON thô.
Trong trường hợp đó, một diễn viên đơn giản <Fruit> fruitString
hoặc fruitString as Fruit
là giải pháp duy nhất (xem các câu trả lời khác). Bạn sẽ không bao giờ có thể cải thiện điều này vào thời gian biên dịch. [ Chỉnh sửa: Xem câu trả lời khác của tôi về<const>
]!
Tuy nhiên, rất dễ gặp phải lỗi tương tự khi sử dụng các hằng số trong mã của bạn mà không bao giờ có ý định thuộc loại chuỗi . Câu trả lời của tôi tập trung vào kịch bản thứ hai đó:
Trước hết: Tại sao hằng số chuỗi 'ma thuật' thường tốt hơn enum?
- Tôi thích cách một chuỗi liên tục trông so với enum - nó nhỏ gọn và 'javascripty'
- Có ý nghĩa hơn nếu thành phần bạn đang sử dụng đã sử dụng hằng chuỗi.
- Phải nhập một loại 'enum' chỉ để có được giá trị liệt kê có thể gây rắc rối cho chính nó
- Bất cứ điều gì tôi làm tôi muốn nó được biên dịch an toàn vì vậy nếu tôi thêm loại bỏ một giá trị hợp lệ khỏi loại kết hợp hoặc gõ nhầm thì nó PHẢI đưa ra lỗi biên dịch.
May mắn thay khi bạn xác định:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... Bạn đang thực sự xác định một tập hợp các loại trong đó 'missing'
thực sự là một loại!
Tôi thường gặp phải lỗi 'không thể gán được' nếu tôi có một chuỗi như 'banana'
trong bản thảo của mình và trình biên dịch nghĩ rằng tôi có nghĩa đó là một chuỗi, trong khi tôi thực sự muốn nó thuộc loại banana
. Trình biên dịch có thể thông minh đến mức nào sẽ phụ thuộc vào cấu trúc mã của bạn.
Đây là một ví dụ về khi tôi gặp lỗi này ngày hôm nay:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Ngay khi tôi phát hiện ra rằng 'invalid'
hoặc 'banana'
có thể là một loại hoặc một chuỗi, tôi nhận ra rằng tôi chỉ có thể xác nhận một chuỗi vào loại đó . Về cơ bản, truyền nó cho chính nó và nói với trình biên dịch rằng tôi không muốn đây là một chuỗi !
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
Vì vậy, có gì sai khi chỉ 'đúc' thành FieldErrorType
(hoặc Fruit
)
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
Nó không biên dịch thời gian an toàn:
<FieldErrorType> 'invalidddd'; // COMPILER ALLOWS THIS - NOT GOOD!
<FieldErrorType> 'dog'; // COMPILER ALLOWS THIS - NOT GOOD!
'dog' as FieldErrorType; // COMPILER ALLOWS THIS - NOT GOOD!
Tại sao? Đây là bản đánh máy nên đây <FieldErrorType>
là một khẳng định và bạn đang nói với trình biên dịch một con chó là FieldErrorType ! Và trình biên dịch sẽ cho phép nó!
NHƯNG nếu bạn làm như sau, thì trình biên dịch sẽ chuyển đổi chuỗi thành một kiểu
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Chỉ cần coi chừng những lỗi chính tả ngu ngốc như thế này:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Một cách khác để giải quyết vấn đề là bằng cách truyền đối tượng cha:
Định nghĩa của tôi là như sau:
loại xuất FieldName = 'số' | 'Hết hạn' | 'cvv'; loại xuất FieldError = 'none' | 'mất tích' | 'không hợp lệ'; kiểu xuất FieldErrorType = {field: FieldName, error: FieldError};
Giả sử chúng ta gặp lỗi với lỗi này (chuỗi không thể gán lỗi):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Chúng ta có thể 'khẳng định' toàn bộ đối tượng như FieldErrorType
thế này:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Sau đó, chúng tôi tránh phải làm <'invalid'> 'invalid'
.
Nhưng còn lỗi chính tả thì sao? Không <FieldErrorType>
chỉ khẳng định bất cứ điều gì có quyền thuộc loại đó. Không phải trong trường hợp này - may mắn là trình biên dịch S phàn nàn nếu bạn làm điều này, bởi vì nó đủ thông minh để biết điều đó là không thể:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit
?