일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- RTK Query
- useAppDispatch
- 호이스팅
- 리터럴 타입
- 공변성
- CORS
- map
- ESlint
- Promise
- autosize
- 이분 검색
- dfs
- 인터섹션
- 결정 알고리즘
- app router
- 반공변성
- Jest
- 투포인터
- React
- tailwind
- recoil
- SSR
- Cypress
- async/await
- webpack
- CI/CD
- 태그된 유니온
- 타입 좁히기
- 무한 스크롤
- TS
- Today
- Total
짧은코딩
TS 기본 지식 본문
함수 리턴값 타입 위치
function add(x: number, y: number): number {
return x + y;
}
리턴값 타입 위치는 이렇게 매개변수 뒤쪽에 붙여야한다.
function add(x: number, y: number): number;
function add(x, y) {
return x + y;
}
혹은 이렇게 타입만 선언하고 다음에 내용을 선언하는 경우도 있다.
화살표 함수
const add: (x: number, y: number) => number = (x, y) => x + y;
이렇게 매개변수의 타입 위치가 찾기 어렵게 있다. 이런 경우 타입을 다 지웠을 때 js 문법에 맞게 되도록 코딩을 하면 어느정도 맞다.
type Add = (x: number, y: number) => number;
const add: Add = (x, y) => x + y;
혹은 이렇게 type을 빼줄 수 있다.
interface Add {
(x: number, y: number): number;
}
const add: Add = (x, y) => x + y;
interface를 통해서도 타입을 선언할 수 있고 많이 사용하는 방식이다.
객체
const obj: {lat:number, lon:number} = {lat:37.5, lon:127.5}
이렇게 두면된다. 마찬가지로 타입 부분을 지웠을 때 js 문법에 맞아야한다.
배열
const arr: string[] = ["123", "456"];
[]를 붙여주면 된다.
const arr2: Array<number> = [123, 456];
이렇게 Array 제네릭을 사용할 수 있다.
튜플
튜플은 개수가 고정된 배열이다.
const arr: [number, number, string] = [123, 456, "hello"];
이렇게 각각 타입을 만들면된다.
원시값
const f: true = true;
const g: 5 = 5;
이렇게 값 자체를 고정할 수 있다. 왜냐하면 const는 항상 고정된 값이기 때문이다.
타입 추론
-const
ts에서 const를 하면 스스로 타입을 알아챈다.
const a: string = '5';
근데 여기서 string이나 number 타입을 주게되면 범위가 넓어져서 더 안좋아진다.
const a = '5';
따라서 const의 경우에는 그냥 써주는 것이 좋다.
-ts 타입 추론
ts는 타입을 거의 예측한다. 따라서 ts가 제대로 예측을 하면 굳이 타입 선언을 할 필요는 없다. 만약 예측하지 못하거나 any로 예측하면 그 때 타입을 선언해줘도 된다.
as
let a = 123;
a = 'hello' as unknown as number;
as는 강제로 타입을 바꾸고 에러가 사라진다.
never 타입
빈 배열은 never 타입이라 반드시 타입을 지정해야한다.
-never에 대한 더 자세한 글
https://ui.toast.com/weekly-pick/ko_20220323
type 지정하고 사용하기
사진처럼 타입을 지정해두면 이 타입을 선언하는 변수에서 자동적으로 값을 추천해준다.
혹은 이렇게 2가지 중 하나를 추천받을 수도 있다.
enum
const enum EDirection {
Up,
Down,
Left,
Right
}
const a = EDirection.Up;
UP은 0, Down은 1, Left은 2, Rigjt은 3이라서 이렇게 하면 a = 0이다.
const enum EDirection {
Up = 3,
Down,
Left,
Right
}
const a = EDirection.Up;
이렇게 초기 값을 지정해주면 순서대로 3, 4, 5 ,6이 되고 a는 3이다.
-객체로 표현한 방법
const ODirection = {
Up: 0,
Down: 1,
Left: 2,
Right: 3,
} as const;
객체로 표현하는 것이 좀 더 좋다. as const를 쓰면 타입이 더 명확해진다. 안 사용하면 타입이 number가 된다.
readonly는 읽기 전용이라 수정을 못한다. 실제 코딩할 때 앞에 붙여서 사용해도 된다.
typeof
obj는 값이다. 근데 타입으로 사용하고 싶으면 typeof를 붙이면 된다.
keyof를 붙이면 키들 뽑아내고 싶을 때 사용하면 된다. 즉 a, b, c를 타입으로 사용할 수 있다.
이렇게 하면 value들의 타입값만 가져온다.
type와 interface
type A = { a: string };
const a: A = { a: "hello" };
interface B {
a: string;
}
const b: B = { a: "hello" };
이렇게 type와 interface로 사용할 수 있다. 둘의 차이점은 type은 간단한거에 사용하고 interface는 좀 더 객체 지향적인 것을 할 때 사용하면 좋다.
interface A {
a: string;
}
interface A {
b: string;
}
const obj1: A = { a: "hello", b: "world" };
type B = { a: string };
type B = { b: string };
interface는 이름을 중복으로 지어도 되지만 type는 중복으로 지으면 안된다.
&
type A = { hello: "world" } & { zero: "cho" };
const a: A = { hello: "world", zero: "cho" };
& 연산자는 객체에서 사용할 수 있다. 모든 속성이 다 있어야 한다.
type Animal = { breath: true };
type Poyouryu = Animal & { breed: true };
type Human = Poyouryu & { think: true };
const z: Human = { breath: true, breed: true, think: true };
이렇게 상속의 개념을 사용할 수 있다.
interface
interface A {
breath: true;
}
interface B extends A {
bread: true;
}
const b: B = { breath: true, bread: true };
JAVA에서 처럼 이렇게 확장해서 사용이 가능하다.
type Animal = { breath: true };
type Poyouryu = Animal & { breed: true };
type Human = Poyouryu & { think: true };
const z: Human = { breath: true, breed: true, think: true };
interface A {
breath: true;
}
interface B extends Human {
bread: true;
}
const b: B = { breath: true, bread: true, think: true };
type과도 같이 사용이 가능하다.
잉여 속성 검사
interface A {
a: string;
}
const obj = { a: "hello", b: "world" };
const obj1: A = obj;
interface 안에 b가 없는데
const obj1: A = { a: "hello", b: "world" };
이렇게 하면 에러가 난다. 하지만 맨 위 코드처럼 한게를 거치면 에러가 나지 않는다.
void 타입
만약 함수에 리턴 값이 있으면 void 타입을 넣으면 안된다. 대신에 undefined를 return 하는 것은 된다. 하지만 null을 리턴하는 것은 안된다.
=> 따라서 return; 이렇게만 있거나 리턴 값이 없는 함수가 void 타입이 된다.
function a(callback: () => void): void {}
interface Human {
talk: () => void;
}
void는 3가지 종류가 있다.
1. return 값이 void
2. 매개 변수가 void
3. 메서드가 void
이 중에서 매개 변수가 void, 메서드가 void 이 2가지는 리턴 값이 존재할 수 있다. 즉, 직접적인 return 값이 void인 경우 제외하고 리턴 값이 있을 수 있다.
-예시1
declare function forEach(arr: number[], callback: (el: number) => void): void;
let target: number[] = [];
forEach([1, 2, 3], (el) => target.push(el));
이런 경우에는 callback에서 매개변수 값이 number이다. 하지만 void로 해도 에러가 발생하지 않는다. 왜냐하면 void는 어떤 값으로 해도 상관 없다는 의미이기 때문이다.
여기서 declare는 외부에서 만들어져 있는 함수나 변수를 가져와서 쓰겠다는 의미이다.
-예시2
interface A {
talk: () => void;
}
const a: A = {
talk() {
return 3;
},
};
const b = a.talk();
이렇게 하면 원래 b에는 3이 들어있어야 한다. 하지만 void는 이를 무시하고 b는 void가 된다.
이렇게 나온다. 따라서 return 값의 타입이 void이면 return 값을 안 넣는 것이 맞다.
-강제 타입 변환
const b = a.talk() as unknown as number;
만약 자신이 책임질 수 있으면 이렇게 타입을 변경할 수 있다. 하지만 이 방식은 웬만하면 안하는 것이 좋다.
any와 unknown
결론부터 말하면 any 쓸 바엔 unknown을 쓰는 것이 낫다.
왜냐하면 any를 사용하면 ts가 타입 검사를 아예 하지 않는다. 따라서 ts를 쓰는 의미가 없어진다.
unknown은 개발자가 직접 타입을 정해줄 수 있다. Error의 타입은 unknown이다.
'TS > TS(with ZeroCho)' 카테고리의 다른 글
TS와 건망증 (0) | 2022.08.20 |
---|---|
리턴값, 매개변수의 대입 범위 (0) | 2022.08.20 |
타입을 만드는 법 (0) | 2022.08.20 |
제네릭 (0) | 2022.08.18 |
TS 기본 기식(2) (0) | 2022.08.17 |