在几种情况下,您会遇到此特定错误。对于OP,有一个明确定义为字符串的值。因此,我必须假设这可能来自下拉列表,Web服务或原始JSON字符串。
在这种情况下,简单的强制转换<Fruit> fruitString
或是fruitString as Fruit
唯一的解决方案(请参阅其他答案)。您将永远无法在编译时对此进行改进。[ 编辑:查看我关于的其他答案<const>
!
但是,在代码中使用原本不打算为string类型的常量时,很容易遇到相同的错误。我的回答集中在第二种情况:
首先:为什么“魔术”字符串常量通常比枚举更好?
- 我喜欢字符串常量与枚举的外观-它紧凑且“ javascripty”
- 如果您正在使用的组件已经使用了字符串常量,则更有意义。
- 仅仅为了获取枚举值而必须导入“枚举类型”本身可能很麻烦
- 无论我做什么,我都希望它是编译安全的,因此,如果我添加从联合类型中删除有效值或输入错误的类型,则它必须给出编译错误。
幸运的是,当您定义:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
...您实际上是在定义类型的并集,而'missing'
实际上是一个类型!
如果'banana'
我的打字稿中有一个字符串,并且编译器认为我将其表示为字符串,那么我经常会遇到“无法分配”错误,而我真的希望它是type 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 ='数字'| 'expirationDate'| 'cvv'; 导出类型FieldError ='none'| '缺少'| '无效'; 导出类型FieldErrorType = {field:FieldName,错误:FieldError};
假设我们对此产生了错误(字符串不可分配错误):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
我们可以FieldErrorType
像这样“断言”整个对象:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
这样我们就不必做<'invalid'> 'invalid'
。
但是错别字呢?不<FieldErrorType>
只是断言无论是在右边是此类型。并非在这种情况下-幸运的是,如果您这样做,编译器将抱怨,因为它足够聪明,知道它是不可能的:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit
?