function 함수(x :number | string){
return x + 1
}
이렇게 함수를 지정해주면 에러가 난다.
타입스크립트는 여러 개의 타입을 이용할 때
타입을 확정지어주지 않으면 까다로운 타입스크립트는 오류를 내기 때문에,
narrowing을 꼭 해주어야 한다.
이럴 때 해결하는 방법이 narrowing이나 assertion을 이용하는 건데,
assertion에 대한 내용은 저번 숙제 게시글에 있으니
기본적은 narrowing이나 정리해보도록 하장
function 함수(x: number | string){
if (typeof x === 'string'){
return x + '1';
} else {
return x + 1;
}
}
제일 직관적이고 쉬운 방법이당
else {}
이거 없으면 에러가 난다.
너 이거는 return 없어~ 하고 오류 날까봐 알려주는 건데,
tsconfig.js 에서 "noImplicitReturns": false,
이걸 넣어주면 오류가 안난다.
그래도 엄격하게 쓰는 게 좋으니 else를 빼먹지 말ㄹ도록 하자
in 연산자로 object 자료 narrowing하는 방법
object에서 서로 다른 유니크한 속성들을 가지고 있다면
if (이 파라미터가 a라는 속성을 안에 가지고 있냐)
이런 if문을 써도 narrowing이 가능하다.
if (키값 in object자료형)
이렇게 써주면 됨.
type Fish = { swim: string };
type Bird = { fly: string };
이럴 때 typeof 를 쓸 수가 없다.
typeof 는 말그대로 string, number, boolean 같은 타입만 가져올 수 있기 때문에,
두 다른 속성을 가진 오브젝트를 비교할 수가 없음.
function 함수(animal: Fish | Bird){
if ('swim' in animal) {
return animal.swim
}
return animal.fly
}
그럴 때 위처럼 in을 쓸 수가 있다.
서로 배타적인 속성을 지닐 때 사용가능하다.
type Car = {
wheel : '4개',
color : string
}
type Bike = {
wheel : '2개',
color : string
}
type Transport = Car | Bike
타입 Car, Bike는 둘 다 wheel
라는 동일한 키를 갖지만 키의 값은 각 '4개', '2개'로 다른 값을 갖는다.
function isCar(x : Transport){
if (x.wheel === '4개'){
console.log('the car is ' + x.color)
} else {
console.log('the bike is ' + x.color)
}
}
함수 isCar 인자는 Transport 타입을 갖는다.
interface Shape {
kind: "circle" | "square";
radius?: number;
sideLength?: number;
}
이런 interface가 있다 칠 때,
도형의 종류가 원일지, 사각형일지 모르므로 radius나 sideLength의 값을 ? 로 두었다.
function getArea(shape: Shape) {
return Math.PI * shape.radius ** 2;
}
만약 면적을 구하는 함수를 이렇게 나타낸다면 당연히 오류가 난다
왜냐면 radius가 있는지 없는지도 모르는데 다짜고짜 쓰라고 하니 예민킹 타입스크립트는 안된다고 말하는 거다
function getArea(shape: Shape) {
if (shape.kind === "circle") {
return Math.PI * shape.radius ** 2;
}
}
그렇다고 if를 사용해서 얘 kind는 원이야! 라고 한다 해봤자 안된다
어차피 radius 모르기는 마찬가지니깐..
function getArea(shape: Shape) {
if (shape.kind === "circle") {
return Math.PI * shape.radius! ** 2;
}
}
radius는 있어! 있다구! 하고 말해놓으면 오류신세는 면할 수 있다
하지만.. radius를 안 써버리면.. 또 오류가 날 것이야
이때 타입 지정방식 자체를 바꾸어 주면 된다.
interface Circle {
kind: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
이렇게 되면 Shape 라는 타입은 공통적으로 kind 라는 속성을 가지고, 각각 고유의 필수적인 속성도 가지게 되는 것이다.
function getArea(shape: Shape) {
return Math.PI * shape.radius ** 2;
}
이러면 보다 정확한 오류를 알려주게 된다.
이때 if문을 사용해주면 오류없이 ts가 타입을 잘 감지하게 된다.
이렇게 코드를 더 직관적으로 작성할 수 있고,
공통적인 property를 갖게 만들어 구분이 쉽도록 한다.
x instanceof Foo
는 Foo 라는 프로토타입체인 안에 x라는 인스턴스가 있나 확인하는 것이다.
function logValue(x: Date | string) {
if (x instanceof Date) {
console.log(x.toUTCString());
} else {
console.log(x.toUpperCase());
}
}
if (저 변수가 undefined일 경우) 이렇게 해줘~
살다보면 이런 경우를 많이 맞이하게 된다.
이런 상황을 방어해 안전하게 하고 넘어가는게 좋기 때문이다.
function 함수(a : string | undefined){
if (typeof a === 'string') {
} else {
}
}
당연히 이렇게 쓰면 된다.
그런데 이 코드를 한 줄로 줄일 수가 있음
function 함수(a : string | undefined){
if (a && typeof a === 'string') { ...
그러니까,
if (변수 && typeof strs === "string") {}
이렇게 사용하면 변수가 undefined라면 undefined가 남아서 if문이 실행되지 않고,
(if문 조건식안에 falsy 값이 남으면 if문 실행XXX)
변수가 string 타입이면 if문이 실행된다.
즉 null, undefined를 쉽게 거를 수가 있는 것이다.
원래 &&
이건 조건식 2개가 참이면 전부 참으로 판정해주세요~ 라는 논리연산자인데 여러 개를 사용하면 이상한 현상이 있다.
자료형
을 넣으면,falsy 값
은 false와 유사한 기능을 하는 null, undefined, NaN
이런 값들을 의미1 && null && 3 // null이 남음
undefined && '안녕' && 100 // undefined 남음
타입스크립트 계속 정리해주세요 ..!!