❗ Narrowing
타입스크립트 프로그램에서 변수는 덜 정확한 타입에서 더 정확한 타입으로 변할 수 있다.
이 과정을 type narrowing이라고 한다, 간략하게 말하면 타입의 범위를 좁히는 것이다.
타입 에러를 피하기 위해 아래처럼 type narrowing을 이용할 수 있다.
// ===== narrowing X =====
function narrowExample (x: number|string){
return x+1
}
narrowExample(123) //error
// ===== narrowing =====
function narrowExample (x: number|string){
if(typeof x === 'string'){
return console.log(x + '1') //1231
}
else{
return console.log(x + 1) //124
}
}
narrowExample(123)
// ===== narrowing X =====
function narrowExample_2 (x: number|string){
let array :number [] = [];
array[0] = x;
return console.log(array[0])
}
narrowExample_2(123) //error
// ===== narrowing =====
function narrowExample_2 (x: number|string){
let array :number[] = [];
if(typeof x === 'number'){
array[0] = x
return console.log(array)
}
else{
}
}
narrowExample_2(123) //[123]
✔ if문 쓰고 else문까지 넣어줘야함, 안넣어주면 간혹 에러가 뜰 수도 있음
✔ 꼭 if문이 아니더라고 사용하려는 변수의 타입을 특정해준다면 다 가능함 -> ex) instanceof, for in 문, typeof 변수
👍 간단하게 Narrowing을 사용하기 위해선 assertion 문법도 좋다. assertion은 타입을 잠깐 덮어씌우는 것이다. 해당 문법을 사용하면 if문 보다 많이 간략해진다. 예시를 바로 살펴보자
// if를 활용한 narrowing
function narrowExample_2 (x: number|string){
let array :number[] = [];
if(typeof x === 'number'){
array[0] = x
return console.log(array)
}
}
narrowExample_2(123) //[123]
// assertion을 활용한 narrowing
function narrowExample_2 (x: number|string){
let array :number[] = [];
array[0] = x as number;
return array
}
narrowExample_2(123) //[123]
하지만 assertion는 용도를 제대로 파악한 뒤 사용을 해야한다.
✔ 어떠한 변수의 타입을 확정지을 때 사용한다.
-> 타입을 변경하지는 못한다.
✔ 무슨 타입이 들어올지 100% 확실할 때 써야한다.
-> 왜 그런지 예제를 가볍게 보자
let array :number[] = [];
function narrowExample_2 (x: number|string){
array[0] = x as number;
return array
}
narrowExample_2(123) //[123] -> 결과 출력
let array :number[] = [];
function narrowExample_2 (x: number|string){
array[0] = x as number;
return array
}
narrowExample_2('123') //옳지못한 타입이 들어갔지만 에러가 안뜨고 결과도 안뜬다.
예제를 보면 바로 보이겠지만.... 버그 추적을 못한다... 꽤나 치명적이다...
그래서 사실 해당 문제점 때문에 assertion 문법이 아니라 if문을 쓴다
✔ 남이 짠 코드를 수정하는데 타입 에러가 도대체 왜 뜨는지 모를 때 비상용으로 쓴다고 한다.
-> 이 한 줄로 assertion 문법에 대한 용도 설명이 끝이 난다. "비상용"
❓ 문제 1
숫자여러개를 array 자료에 저장해놨는데
가끔 '4', '5' 이런 식의 문자타입의 숫자가 발견되고 있다.
이걸 클리닝해주는 함수가 필요하다.
클리닝함수( ['1', 2, '3'] ) 이렇게 숫자와 문자가 섞인 array를 입력하면
[1,2,3] 이렇게 숫자로 깔끔하게 변환되어 나오는 클리닝함수를 만들어오고 타입지정까지 확실히 해보자.
✌ 풀이 1
let array = [1,'2',3]
function narrowExample_3(x : number|string){
array.push(x)
return array
}
narrowExample_3(5)
function cleaningFunction_1(clean_array: (number|string)[]){
let clean_array_result :number[] = [];
clean_array.forEach((element) => {
if (typeof(element) === 'string'){
clean_array_result.push(parseInt(element))
}
else{
clean_array_result.push(element)
}
});
return console.log(clean_array_result)
}
cleaningFunction_1(array)
1. 새로운 배열 생성
2. forEach문으로 배열 반복
3. if문을 활용하여 배열 안에 있는 객체가 문자열이라면 정수형으로 변환 후 새로운 배열에 push
4. else문을 활용하여 배열 안에 있는 객체가 문자열이 아니라면 값 그대로 새로운 배열에 push
✌ 풀이 2
let array = [1,'2',3]
function narrowExample_3(x : number|string){
array.push(x)
return array
}
narrowExample_3(5)
function cleaningFunction_2(clean_array: (number|string)[]){
clean_array.forEach((element,index) => {
if (typeof(element) === 'string'){
clean_array.splice(index,index,parseInt(element))
}
});
return console.log(clean_array)
}
cleaningFunction_2(array)
1. forEach문으로 배열 반복
2. if문을 활용하여 배열안에 있는 객체가 문자열이라면 해당 인덱스의 값을 정수형으로 변경
❓ 문제 2
let teacher_1 = { subject : 'math' }
let teacher_2 = { subject : ['science', 'english'] }
let teacher_3 = { subject : ['science', 'art', 'korean'] }
지금 여러 변수에 선생님이 가르치고 있는 과목이 저장이 되어있다.
과목 1개만 가르치는 쌤들은 문자 하나로 과목이 저장이 되어있고
과목 2개 이상 가르치는 쌤들은 array 자료로 과목들이 저장되어있다.
teacher_1 선생님을 object 자료를 집어넣으면
그 선생님이 가르치고 있는 과목중 맨 뒤의 1개를 return 해주는 함수를 만들어보자.
그리고 타입지정도 엄격하게 해보자
✔ 답 예제
함수( { subject : 'math' } ) // 'math'
함수( { subject : ['science', 'art', 'korean'] } ) // 'korean'
함수( { hello : 'hi' } ) // 타입에러
✌ 풀이
function teacherSubject(array: {subject : string|string[]}){
if(typeof(array.subject) === 'string'){
return console.log(array.subject)
}
else if(typeof(array) === 'object'){
return console.log(array[array.subject.length-1])
}
else{
}
}
teacherSubject({ subject : 'math' }) // 'math'
teacherSubject({ subject : ['science', 'english'] }) // 'english'
teacherSubject({ subject : ['science', 'art', 'korean'] }) // 'korean'
teacherSubject({ hi : 'ih' }) // 키 값이 subject가 아니므로 타입 에러
1. array 매개변수의 key는 subjet가 들어가야하고 value값을 문자열이나 문자열로 이루어진 타입만을 받아오게 지정한다.
2. if문에서 array 변수의 value가 문자열이면 그대로 출력
3. else if에서 array 변수의 value가 배열이면 그대로 배열의 가장 끝에 있는 객체를 출력
'자바스크립트 - TypeScript' 카테고리의 다른 글
[TypeScript] 타입을 파라미터로 입력하는 Generic (0) | 2022.12.22 |
---|---|
[TypeScript] interface를 이용한 타입 지정 (0) | 2022.11.22 |
[TypeScript] 리터럴 타입 (Literal Types)에 대하여 (0) | 2022.11.18 |
[Typescript] 기본 필수 문법 (0) | 2022.10.29 |