이 특정 오류를 발생시키는 몇 가지 상황이 있습니다. OP의 경우 명시 적으로 문자열로 정의 된 값이있었습니다 . 따라서 이것은 드롭 다운 또는 웹 서비스 또는 원시 JSON 문자열에서 비롯된 것으로 가정해야합니다.
이 경우 간단한 캐스트 <Fruit> fruitString
또는 fruitString as Fruit
유일한 해결책입니다 (다른 답변 참조). 컴파일 타임에는 이것을 향상시킬 수 없습니다. [ 편집 :에 대한 다른 답변보기<const>
]!
그러나 코드에서 문자열 유형이 아닌 상수를 사용할 때이 동일한 오류가 발생하기 쉽습니다 . 내 대답은 두 번째 시나리오에 중점을 둡니다.
우선 : 왜 '매직'문자열 상수가 종종 열거 형보다 낫습니까?
- 나는 문자열 상수가 열거 형과 열거 형을 좋아합니다-컴팩트하고 '자바 스크립트'
- 사용중인 구성 요소가 이미 문자열 상수를 사용하는 경우 더 의미가 있습니다.
- 열거 형 값을 얻기 위해 'enum type'을 가져와야하는 것은 그 자체로 까다로울 수 있습니다
- 내가 무엇을하든 컴파일 안전 하기를 원하므로 공용체 유형에서 유효한 값을 제거하거나 잘못 입력하면 컴파일 오류가 발생해야합니다.
다행히도 다음을 정의 할 때
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... 당신은 실제로 정의하고 유형의 조합'missing'
실제로 타입입니다!
필자는 'banana'
typescript와 같은 문자열이 있고 컴파일러 가 문자열을 의미 한다고 생각 하는 경우 '할당 할 수 없음'오류가 종종 발생 하지만 실제로는 유형이되기를 원했습니다 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!
왜? 이것은 typescript이므로 <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 = {필드 : 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
합니까?