Unknown and Never
Unknown
Unknown은 검색하면
꽤 다양한 용도를 찾을 수 있는 타입 중 하나입니다.
이는 any 타입의 자매처럼 작동합니다. any가 모호함을 나타내는 반면
unknown은 세부사항을 필요로 합니다.
JSON 파서를 감싸는 것이 좋은 예시가 될 수 있습니다.
JSON 데이터는 서로 다른 형식으로 제공되며,
json 파싱 함수의 작성자는 데이터의 형식을 알 수 없습니다.
그 형식은 함수를 호출한 사람이 알고 있습니다.
// jsonParser에 마우스를 올리면, 반환 타입이 any이고
myAccount 또한 동일합니다.
이는 Generic을 이용하여 해결할 수 있지만
unknown으로 해결할 수도 있습니다.
const jsonParser = (jsonString: string) => JSON.parse(jsonString);
const myAccount = jsonParser(`{ "name": "Dorothea" }`);
myAccount.name;
myAccount.email;
// myOtherAccount 객체는 TypeScript에 타입이 선언되기 전까지
사용될 수 없습니다. 이것은 API를 사용하는 사람이
올바르게 타입을 정의하는지 생각하게끔 해 줍니다.
const jsonParserUnknown = (jsonString: string): unknown => JSON.parse(jsonString);
const myOtherAccount = jsonParserUnknown(`{ "name": "Samuel" }`);
myOtherAccount.name;
// Unknown은 훌륭한 도구입니다. 더 자세히 알아보고 싶다면 다음 자료를 읽어보세요:
https://mariusschulz.com/blog/the-unknown-type-in-typescript
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type
Never
TypeScript는 코드 흐름 분석을 지원하기 때문에,
코드가 논리적으로 발생할 수 없는 경우를 나타낼 수 있어야 합니다.
예를 들어, 아래 함수는 반환되지 않습니다:
type User = { name: string };
const myUserAccount = jsonParserUnknown(`{ "name": "Samuel" }`) as User;
myUserAccount.name;
// 타입에 마우스를 올리면, 이것이 절대로 발생할 수 없다는 것을 의미하는
() => never 타입이라는 것을 알 수 있습니다.
이러한 값은 다른 값과 마찬가지로 여전히 전달될 수 있습니다.
const neverReturns = () => {
// 첫 번째 줄에서 throw하는 경우
throw new Error("Always throws, never returns");
};
// 함수의 리턴값을 never로 작성하는 것은
JavaScript 런타임 시 예측 불가능하거나
API를 사용하는 사람이 type을 사용하지 않았을 때 유용합니다.
const myValue = neverReturns();
// 타입 정의는 user가 전달되어야 하지만
JavaScript에 이를 보장할 수 없는
충분한 탈출구가 있음을 의미합니다.
never를 반환하는 함수를 사용하면
불가능한 위치에 추가적인 코드를 사용하게끔 해 줍니다.
이는 더 나은 에러 메시지를 보여주거나
파일 또는 반복문과 같은 자원을 닫는 데 유용합니다.
never는 주로 switch문이 완전하다는 것을 보장할 때 사용됩니다.
E.g., 모든 경우가 다뤄짐을 의미합니다.
enum과 완전한 switch문이 있습니다.
enum에 새 옵션(예를 들면 Tulip?)을 넣어보세요.
const validateUser = (user: User) => {
if (user) {
return user.name !== "NaN";
}
// 타입 시스템에 따르면, 아래 코드는 절대 실행 될 수 없는데,
// 이는 neverReturns의 반환 타입에 해당합니다.
return neverReturns();
};
// 새로운 꽃의 타입이 never로 변환될 수 없다는
컴파일 에러가 발생할 것입니다.
교차 타입에서의 Never
Never는 교차타입에서
자동적으로 제거되는 타입입니다.
enum Flower {
Rose,
Rhododendron,
Violet,
Daisy,
}
const flowerLatinName = (flower: Flower) => {
switch (flower) {
case Flower.Rose:
return "Rosa rubiginosa";
case Flower.Rhododendron:
return "Rhododendron ferrugineum";
case Flower.Violet:
return "Viola reichenbachiana";
case Flower.Daisy:
return "Bellis perennis";
default:
const _exhaustiveCheck: never = flower;
return _exhaustiveCheck;
}
};
// NeverIsRemoved 타입을 보면,
string | number인 것을 확인할 수 있습니다.
never에는 할당할 수 없기 때문에 런타임에서는 절대 발생하지 않을 것이기 때문입니다.
이 항목은 example:conditional-types에서 많이 사용됩니다.
type NeverIsRemoved = string | never | number;