const activeUsers: [] = []
activeUsers.push("steven") // error
이는 우리가 acriveUsers
에 빈배열이라고 알려줬기 때문에 생기는 에러이다. 그래서 무언가를 넣으려고 하면 에러가 생기는 것이다.
그래서 배열 대괄호 앞에 어떤 타입인지 알려줘야 한다
const activeUsers: string[] = []
activeUsers.push("steven") // 에러없음!
이 경우 문자열 배열이 된다고 알려주는 것이며 빈배열로 시작하던 문자열을 넣고 문자열 배열로 시작하던 상관은 없다
만약 지정하지 않고 타입 추론으로 activeUsers =[]
이렇게 선언할 경우 any[]
로 가정된다
다른 방식으로도 표현할 수 있는데
const activeUsers: Array<string> = []
activeUsers.push("steven") // 에러없음!
위에서 얘기한 string[]
과 같은 동작을 한다. 또한 커스텀도 가능한데
type Point = {
x: number;
y: number;
}
const coords: Point[] = []
coords.push({x: 23, y:45})
이와 같이 Point
타입과 같은 커스텀 객체로 이루어진 배열이다 라고 애너테이션 할 수 있다
const board: string[] = [["X","O","X"],["X","O","X"],["X","O","X"]]// error
const board: string[][] = [["X","O","X"],["X","O","X"],["X","O","X"]]// good
위처럼 2차원 배열시 string[][]
처럼 애너테이션을 넣으면 된다!
그러면 3차원 배열은?? number[][][]
하면 되는데 두단계로 중첩된 배열보다 훨씬 복잡해보인다. 다른 방법을 찾아서 해보자 타입 별칭을 통해도 좋고..
유니온 타입을 이용하면 여러 타입의 값을 가질 수 있다. 사용법은 간단히 |
로 사용되는데
런타임 동안 어떤 타입의 값을 사용할지 안다면 굳이 유니온 타입을 사용하진 않아도 된다.
let age:number | string = 21;
age = 23;
age = "24";
처럼 작성해도 동작한다.
하지만 항상 최대한 정확하고 구체적인 타입을 선언해야 한다!
물론 변수나 함수도 이용할 수 있다.
똑같이 파라미터에 유니온 타입으로 작성하면 되는데
function calculateTac(price:number | string, tax:number){
return price * tax
}
이 경우에 price가 number
일수도 string
일수도 있기 때문에 에러가 생긴다.
문자열에 숫자를 곱할수 없기 때문! 이럴땐 어떻게 할까? 바로
를 하면 된다! 쉽게 말해 타입을 확인하는 단계를 추가하는 것
function calculateTac(price:number | string, tax:number){
if(typeof price === "string") price.replace("$","")
}
이경우엔 괜찮아진다. 조건문을 Typescript가 자동으로 체크하기 때문!
이렇게도 가능해진다
function calculateTac(price:number | string, tax:number){
if(typeof price === "string") {
price = parseFloat( price.replace("$",""))
}
return price * tax
}
자동적으로 연산에 도착한 부분까지 typescript가 체크해 주는것이다.
이것이 타입 좁히기(type narrowing)이다
const stuff: (number | string)[] = [1,2,3,4,"age"]
만약 괄호를 입력하지 않는다면 타입을 number
이거나 string[]
로 분리해서 정의된다
그렇기에 괄호로 잘 감싸주는 것이 중요!
물론 number[]
와 string[]
을 둘 다 적는 것도 불가능하다! 숫자나 문자열로 구성된 배열이다라는 뜻이 아니라 숫자 배열 혹은 문자열 배열이다 라는 뜻으로 입력되기 때문!
물론 커스텀 타입또한 유니온 타입에 집어 넣을 수 있다
유니온 타입과 같이 쓰이는 때가 아주 많을 것!
let zero: 0 = 0
zero = 2 // error
zero
는 타입도 0
이며 값도 0
이다. 뭔가 이상한 작성법인데 되게 의미가 없지 않을까 싶다.
대신 유니온 타입을 활용한 리터럴 타입을 활용하는 방법은 유용하다
변수가 작성한 리터럴 값 중 하나를 갖도록 할 수 있기 때문
let mood: "Happy" | "Sad" = "Happy";
mood = "Sad"; // success
mood = "Hi"; // error
이와 같이 특정 변수에 알맞은 값들을 유니온 타입을 활용해 리터럴 타입들을 지정해 놓고 해당 값들만 들어올 수 있도록 활용할 수 있다! 다양한 옵션을 만들 수 있기 때문