2.7 타입스크립트에만 있는 타입을 배우자
2.7 타입스크립트에만 있는 타입을 배우자
타입스크립트에는 any처럼 보지 못한 타입들이 존재한다. 이번 글에서 하나씩 살펴보자.
2.7.1 any
: 타입스크립트에서 지양해야 할 타입
원칙
any 타입은 타입 검사를 포기한다는 선언과 같다. 타입스크립트가 any로 추론하면 타입을 직접 표기해준다.
let str : any = 'hello'
const result = str.tofixed();
- 위와 같이 코드 작성 시 오류가 나지 않음
- 문자열에 tofixed 메서드이 가능해짐
- any 타입은 모든 동작을 허용 -> 타입 검사 불가 -> 타입스크립트 의미 퇴색
아래와 같이 any 타입은 파생 결과물도 any 타입 (사용 지양)
any 타입을 직접 쓸일은 별로 없음 --> 타입스크립트가 타입을 any로 추론할 경우
function (x,y) {
return x+y;
}
- 위와 같이 코드 작성 시
- any 타입으로 추론함
배열
빈 배열을 선언하면 any 타입으로 추론, 에러는 나지 않음
- 하지만 배열에 대한 정확한 타입 검사가 이뤄지지 않음
- 원칙에 따라 직접 타입을 표기해준다.
const arr : string[]= [];
배열에 추가할 경우 -> 타입 바뀜
const arr =[];
arr.push('1');
arr; //1
arr[1] = 3;
arr; //2
- 1 arr은 string[]으로 추론
- 2 arr은 (string | number)[]로 추론
배열 요소 제거할 경우 -> 이전으로 돌아가지 않음
const arr =[];
arr.push('1');
arr;
arr[1] = 3;
arr;
arr.pop();
console.log(arr)
- pop()을 이용해 요소를 제거해도
- 변함없음
연산
숫자나 문자열 타입과 연상할 때 타입이 바뀌기도 함
const a : any = '123';
const an1 = a + 1;
const nb2 = a - 1;
const st1 = a + '1';
- + 연산 --> any (다른 피연산자가 숫자인 경우 a따라 다르기 때문)
- a 가 숫자일지도? --> 결과 숫자
- a가 문자열일지도? --> 결과 문자열
- - , / , * 연산 --> number
- 문자열과 + --> string
명시적으로 any 반환하는 경우
fetch('url').then((response)=>{
return response.json();
}).then ((result)=>{});
const result = JSON.parse('{"hello":"json"}')
- 두 result가 모두 any로 추측됨
방지하기
fetch('url').then<{data : string}>((response)=>{
return response.json();
}).then ((result)=>{});
const result : {hello: string} = JSON.parse('{"hello":"json"}')
2.7.2 unknown
: any와 비슷하게 모든 타입을 대입할 수 있지만, 그 후 어떤 동작도 수행 불가
const a : unknown = 'hello';
const b : unknown = 'world';
a+b;
a.slice();
- unknown 타입을 사용해 동작을 시도할 경우
- 모두 에러로 처리됨
- any와 같이 모든 동작을 허용하는 상황은 발생하지 않음
unknown 역시 직접 표시할 경우는 거의 없고, try catch문에서 unknown을 보게됨
try {
} catch (e) {
console.log(e.message)
}
- e가 unknown이므로 어떠한 동작도 불가능
- catch 문의 e에는 any, unknown 외 타입 표기 불가능
as로 타입을 주장(type assertion) 가능
try {
} catch (e) {
const error = e as Error;
console.log(error.message);
}
또 다른 타입 주장 방법 : <>
--> 나중에 React의 JSX와 출동하므로 <> 대신 as 사용 권장
try {
} catch (e) {
const error = <Error>e;
console.log(error.message);
}
항상 as를 사용해 다른 타입으로 주장하는 건 불가!
- 위와 같은 행위는 실수일 것이라는 에러 메세자
강제 변환 방법
const a : number ='123' as unknown as number
- unknown으로 주장 후 원하는 타입으로 다시 주장
!(non-null assertion) 연산자
: null 과 undefined 가 아님을 주장하는 연산자
- param이 null 또는 undefined일 수도 있으니, slice 사용 불가
function a(param : string | null| undefined) {
param!.slice(3);
}
- !를 사용해 해결
2.7.3 void
- 함수의 반환값을 무시하도록 하는 특수한 타입
- 목적
- 사용자가 함수의 반환값을 사용하지 못하도록 제한
- 반환값을 사용하지 않는 콜백 함수를 타이핑할 때 사용
- 반환값이 없는 경우 void 타입으로 추론
- 자바스크립트 - undefined 반환
- 타입스크립트로 마찬가지지만, 타입은 void
const func: () => void = () => 3;
const value = func();
const func2 = () : void => 3;
const func3: () => void | undefined = () => 3;
- func
- 함수 전체의 타입을 표기한 코드
- 반환값 타입이 void 임에도 3 반환시 에러 X --> undefined 외의 값 반환을 막지 않음
- value
- void를 반환받은 값의 타입은 void가 됨 --> 사용자의 함수 반환값 사용을 막음
- func2
- 반환값만 따로 표기하는 경우 --> 반환값 무시 X
- func3
- void와 다른 타입의 유니언이면 반환값 무시 X
void의 반환값 무시 특성 활용 --> 콜백함수
[1,2,3].forEach((v)=>v);
[1,2,3].forEach((v)=> console.log(v));
- forEach 메서드 : 배열을 순회하며 각 요소에 적용하게 될 콜백함수를 전달
- [1,2,3].forEach((v)=>v);
- 숫자 반환
- [1,2,3].forEach((v)=> console.log(v));
- undefined 반환 (console.log의 반환값이 undefined)
--> 콜백함수의 타입은?
[1,2,3].forEach((v)=> v.toString());
- 위와 같이 사용한 경우는 어떻게??
--> 콜백함수는 미리 타이핑하기 곤란 -> 어떠한 반환값이든 다 받을 수 있는 void 등장!
(v : number) => void
- 콜백함수를 위와 같이 타이핑해 해결
2.7.4 {}, Object
: null과 undefined를 제외한 모든 값
: object와 다른 타입으로 대문자 Object
: 사용할 일은 별로 없지만, if문 안에 unknown 타입을 넣을 때 볼 수 있음
const obj : {} = {name:'zero'}
const arr : {} = []
const func : {} = () => {};
console.log(obj.name)
arr [0]
fun()
- {}타입 변수를 실제로 사용하면 에러 발생
--> 실제로 사용할 수 없어 {} 타입은 대부분 쓸모 없는 타입
객체를 의미하는 object 타입도 마찬가지
- 타입스크립트엔 object가 아닌 객체 리터럴 타입으로 지정하면 객체를 사용 가능하다
{} 타입 + null, undefined 타입 -> unknown과 비슷
const unk : unknown = 'hello';
unk;
if (unk){
unk;
console.log(1)
}
else {
unk;
console.log(2)
}
- 실제로 unknown 타입을 if 문으로 걸러보면 {} 타입이 나옴
2.7.5 never
: 어떠한 타입도 대입 불가
함수 선언문
function neverFunc1(){
throw new Error('에러')
}
const result1 : never = neverFunc1();
- 함수 선언문의 경우 throw를 해도 void 타입 반환
- 에러 발생 : never 타입 변수에 void 타입 변수 대입 불가
함수 표현식
const neverFunc2 = () => {
throw new Error('에러')
}
const result2 : never = neverFunc2();
- 함수 표현식은 never 타입 반환
- never 타입인 변수 result2에 대입 가능
무한 반복문을 가진 함수 (함수 표현식)
const infinite = () => {
while(true){
console.log('무한 반복')
}
}
- 함수가 값을 반환하지 않음 --> 이 경우에도 never 타입 반환
- 함수 선언문일 경우 void 반환
function strOrNum (param : string|number){
if (typeof param === 'string'){}
else if (typeof param === 'number'){}
else{
param;
}
}
- 위의 경우 param은 string 아니 number임
- else 문이 실행될 일은 없어 param은 never로 추론
never 직접 쓰는 경우
function neverFunc1() : never {
throw new Error('에러');
}
function infinite() : never {
while(true){
console.log('무한 반복')
}
}
- 함수 선언문의 경우 void를 반환하므로 never로 직접 표기
2.7.6 타입 간 대입 가능표
'typescript' 카테고리의 다른 글
2.18 ~ 2.22 (1) | 2024.10.06 |
---|---|
타입스크립트 2.13 ~ 2.17 (0) | 2024.09.28 |
2.8 ~ 2.12 (별칭, 인터페이스, 객체 속성, 집합, 상속) (0) | 2024.09.20 |
기본 문법 익히기 (2.4 ~ 2.6) (1) | 2024.09.13 |
타입 스크립트 기본 문법 (2.1 ~ 2.3) (0) | 2024.09.11 |