Есть несколько ситуаций, в которых возникает именно эта ошибка. В случае OP было значение , определенное явно как строка. Поэтому я должен предположить, что, возможно, это произошло из раскрывающегося списка, или веб-службы, или необработанной строки JSON.
В этом случае простое приведение <Fruit> fruitString
или fruitString as Fruit
является единственным решением (см. Другие ответы). Вы никогда не сможете улучшить это во время компиляции. [Изменить: см. мой другой ответ о <const>
]!
Однако очень легко столкнуться с этой же ошибкой при использовании в коде констант, которые никогда не предназначены для строкового типа. Мой ответ сосредоточен на втором сценарии:
Прежде всего: Почему «магические» строковые константы часто лучше, чем перечисления?
- Мне нравится, как строковая константа выглядит по сравнению с перечислением - она компактна и 'javascripty'
- Имеет больше смысла, если компонент, который вы используете, уже использует строковые константы.
- Необходимость импортировать "тип перечисления" только для получения значения перечисления может быть проблемной сама по себе.
- Что бы я ни делал, я хочу, чтобы это было безопасно для компиляции, поэтому, если я добавлю, удаляю допустимое значение из типа объединения или ошибаюсь, он ДОЛЖЕН выдать ошибку компиляции.
К счастью, когда вы определяете:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... вы фактически определяете объединение типов, где 'missing'
на самом деле является типом!
Я часто сталкиваюсь с ошибкой «не назначается», если у меня есть строка типа 'banana'
в моем машинописном тексте, а компилятор думает, что я имел в виду ее как строку, тогда как мне действительно хотелось, чтобы она была типа banana
. Насколько умным будет компилятор, будет зависеть от структуры вашего кода.
Вот пример того, когда я получил эту ошибку сегодня:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Как только я узнал, что 'invalid'
или 'banana'
могут быть типом или строкой, я понял, что могу просто утвердить строку в этот тип. По сути, приведите его к самому себе и скажите компилятору нет, я не хочу, чтобы это была строка!
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
Так что же плохого в том, чтобы просто "преобразовать" в FieldErrorType
(или Fruit
)
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
Это небезопасно во время компиляции:
<FieldErrorType> 'invalidddd'; // COMPILER ALLOWS THIS - NOT GOOD!
<FieldErrorType> 'dog'; // COMPILER ALLOWS THIS - NOT GOOD!
'dog' as FieldErrorType; // COMPILER ALLOWS THIS - NOT GOOD!
Почему? Это машинописный текст, поэтому <FieldErrorType>
является утверждением, а вы сообщаете компилятору, что собака имеет тип FieldErrorType! И компилятор это позволит!
НО, если вы сделаете следующее, компилятор преобразует строку в тип
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Остерегайтесь таких глупых опечаток:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Другой способ решения проблемы - приведение родительского объекта:
Мои определения были следующими:
тип экспорта FieldName = 'number' | 'expirationDate' | 'cvv'; тип экспорта FieldError = 'none' | «пропал без вести» | 'неверный'; тип экспорта FieldErrorType = {field: FieldName, error: FieldError};
Допустим, мы получаем ошибку с этим (строка не назначаемая ошибка):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Мы можем «утвердить» весь объект как FieldErrorType
следующим образом:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Тогда нам не придется делать <'invalid'> 'invalid'
.
А как насчет опечаток? Не <FieldErrorType>
просто утверждает то, что находится справа от этого типа. Не в этом случае - к счастью, компилятор БУДЕТ жаловаться, если вы это сделаете, потому что он достаточно умен, чтобы знать, что это невозможно:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
person
Simon_Weaver
schedule
19.01.2019
export type Fruit
? - person Weather Vane   schedule 23.06.2016