SMALL
1. type[ ] => 지정한 type이 들어가는 배열
let a: number[] = [1, 2]; // typescript가 자동으로 type 추론
let b: string[] = ["li", "1"];
let c: boolean[] = [true];
- typescript가 자동으로 type을 추론해주기 때문에 이런식으로 작성하지 않아도 괜찮음
let c = [true, false];
2. optional
객체에서 key를 선택적으로 가지고 있을 때
// name은 항상 가지고 있고 age는 선택적으로 가지고 있을 때
const player: { name: string; age?: number } = {
name: "nico",
};
- age가 undefined이거나 number ( age?: number | undefined )
3. alias type
type Age = number;
type Player = {
name: string;
age?: Age;
};
const nico: Player = {
name: "nico",
};
const lynn: Player = {
name: "lynn",
age: 12,
};
4. 함수의 return 값
함수가 return하는 type이 무엇인지 알 수 있으면 더 많은 보호장치를 가질 수 있음
function playerMaker(name: string) {
return {
name,
};
}
const uk = playerMaker("nico");
uk.age = 12; // age는 playerMaker 안에 age 라는 type을 지정하지 않았기 때문에 error 발생
function playerMaker(name: string): Player {
return {
name,
};
}
- type은( argument ) 뒤에 지정해주면 됨
화살표 함수의 경우
const playerMaker = (name: string): Player => ({name})
5. readonly
읽기 전용으로 지정
type Player = {
readonly name: string;
age?: Age;
};
nico.name = "lala" // name은 읽기 전용이기 때문에 변경할 수 없음
- name을 readonly로 읽기 전용으로 지정했기 때문에 변경할 수 없음
const numbers: readonly number[] = [1, 2, 3, 4]
numbers.push(1)
const names: readonly string[] = ["1", "2"]
names.push("3")
- 이전 코드와 마찬가지로 읽기 전용이기 때문에 push나 배열을 바꾸는 메서드를 사용할 수 없음
- 단, map이나 filter처럼 배열에 변화를 주지 않는 메서드는 사용 가능
6. Tuple
// platers에 빨간 줄 (error)
const players: [string, number, boolean]= []
- players 배열 안에 값이 3개가 필요함
- 배열 안에 값의 순서는 string, number, boolean
const players: [string, number, boolean]= ['nico', 12, false]
players[0] = 1 // error 발생
- players의 첫 번째 인자는 string이어야 하기 때문에 error 발생
const players: readonly [string, number, boolean]= ['nico', 12, false]
- readonly로 지정할 수 있음
7. unknown
어떤 타입인지 모르는 변수 지정 => API로 응답을 받는데 어떤 값인지 모르는 경우
let a: unknown;
let b = a + 1; // error 발생
- a 의 type이 무엇인지 정해지지 않음
if(typeof a === 'number') { // 범위 내에서 d는 number
let b = a + 1
}
if(typeof a === 'string') {
let b = a.toUpperCase();
}
- a가 number인 경우 b는 a + 1
- a가 string인 경우 b는 a를 toUpperCase 메서드 사용
8. void
return하지 않는 함수에 사용
function hello(): void {
console.log('x')
}
9. never
1) 함수가 절대로 return하지 않는 경우 사용
function hi():never {
return "X"
}
- never은 함수가 절대 return하지 않는 경우이기 때문에 return "X" 부분에 error 발생
function hi():never {
throw new Error("XXX")
}
- 위의 함수는 return을 하지 않고 오류를 발생시키는 함수
2) 타입이 두가지 일 수도 있는 상황에서 발생
// never
function hi(title: string | number) {
if (typeof title === "string") {
title; // string
} else if (typeof title === "number") {
title; // number
} else {
// title은 string 혹은 number를 받기 때문에 이 부분의 title은 절대 작동할 일이 없음
title; // never
}
}
- title은 string 혹은 number를 받는다
- 위의 if (typeof title === "string")과 else if (typeof title === "number") 부분이 있음
- 따라서 마지막 부분인 else 안에 있는 title은 절대 작동할 일이 없어 title의 type은 never로 지정됨
10. Call Signature
내가 원하는 나만의 함수 타입을 만드는 방법
우리가 타입스트립트에게 이 함수가 어떻게 호출되는지 설명해주는 방법
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
- type Add에서 a와 b가 number이고 반환하는 값이 number라고 미리 지정
- 따라서 add 함수에 있는 인자의 type을 지정하지 않고 a + b 는 number를 return해야 하기 때문에 void가 올 수 없음
11. Overloading
함수가 서로 다른 여러 개의 call signatures를 가지고 있는 경우 발생
보통 외부 라이브러리를 사용할 때 발생하게 됨
1) 개념
type Add2 = {
(a: number, b: number) : number
(a: number, b: string) : number
}
// b가 number가 될 수 있고 string도 될 수 있음
const add2 : Add2 = (a, b) => a + b
- b가 number도 될 수 있고 string도 될 수 있기 때문에 error 발생
const add2 : Add2 = (a, b) => {
if(typeof b === "string") return a
return a + b
}
- b가 string인 경우 a만 반환
- b가 string이 아닌 경우 a+b 반환
2) 라이브러리 예시
type Config = {
path: string;
state: object;
};
type Push = {
(path: string): void;
(config: Config): void;
};
const push: Push = (config) => {
if (typeof config === "string") {
console.log(config);
} else {
console.log(config.path);
}
};
3) 파라미터의 갯수가 다른 경우
type Add3 = {
(a: number, b: number): number;
(a: number, b: number, c: number): number;
};
const add3: Add3 = (a, b, c?: number) => {
if (c) return a + b + c;
return a + b;
};
- 인자가 많은 부분은 optional로 지정
12. Polymorphism with generic
다양성을 의미한다.
type SuperPrint = {
(arr: number[]): void
(arr: boolean[]): void
(arr: string[]): void
}
const superPrint: SuperPrint = (arr) => {
arr.forEach(i => console.log(i))
}
superPrint([1, 2, 3, 4])
superPrint([true, false, true])
superPrint(["a", "b"])
- 여기서 number, string, boolean, unknown, void 등은 concrete type
- 우리는 concrete type 대신 placeholder를 작성할 수 있음
- 문제점: call signature 가 3개나 있음
superPrint([1, 2, true, false, "a", "b"])
위와 같이 코드를 작성하면 error 발생
=> 어떤 타입이든 동작하게 하고 싶은 경우
Generic 사용
Generic을 사용하는 이유
- call signature를 작성할 때, 들어올 확실한 타입을 모를 때 generic 사용
- 타입스크립트에 generic을 사용하고싶다고 알림
- generic 이름은 원하는대로 작성 (대개 <T, V>, <TypePlaceholder>)
type SuperPrint = {
<TypePlaceholder>(arr: TypePlaceholder[]): void
}
const superPrint: SuperPrint = (arr) => arr[0]
superPrint([1, 2, true, false, "a", "b"])
- 위와 같이 작성한 경우 generic이 알아서 Placeholder 대신 타입스크립트가 발견한 type으로 바꿔줌
- any와 같지 않고 우리가 하는 요청에 따라 call signature를 생성
type SuperPrint = {
<T, V>(arr: T[], b: V): T;
};
const superPrint: SuperPrint = (arr) => arr[0]
const q = superPrint([1, 2, 3, 4], "X");
- 위와 같이 인자가 여러개인 경우도 사용 가능
function superPrint2<W>(t: W[]) {
return t[0];
}
const t = superPrint2<boolean>([1, 2, 3, 4]); // 배열 안의 값들 error
- W를 boolean으로 지정했기 때문에 1, 2, 3, 4는 number임으로 error 발생함
- => generic이 추론을 해주기 때문에 <number>로 지정할 필요 없음
const [title, setTitle] = useState<number>(0)
- useState를 사용할 때, number 혹은 string 등 타입을 지정하면 number(string) tpye의 useState가 됨
13. interface
type과 같이 오브젝트의 모양을 결정하는 역할을 하지만 type은 interface 보다 조금 더 활용하는 방법이 많음
interface Hello = string
- 위와 같은 방법을 사용할 수 없음
- => interface는 오로지 오브젝트의 모양을 타입스크립트에 설명해주는 역할만 함
// type에 특정 값을 갖게 하기
type Team = "red" | "blue" | "yellow"
type Health = 1 | 5 | 10
interface Gamer {
nickname: string
team: Team
health: Health
}
const uk: Gamer = {
nickname: "ukTheBlood",
team: "red", // "red", "blue", "yellow"
health: 10 // 1 | 5 | 10
}
- 위와 같이 string 같은 타입 뿐만이 아니라 오게 되는 이름까지 정할 수 있음
1) 상속
interface User {
name: string;
}
interface Login extends User {
}
const ukBlood: Login = {
name: "uk",
};
- 위와 같이 상속 기능을 사용할 수 있음
2) merging
interface User {
name: string;
}
interface Login extends User {
age: number;
}
const ukBlood: Login = {
name: "uk",
age: 25,
};
LIST
'Develop_story > TIL(Today I Learned)' 카테고리의 다른 글
채팅방 역 무한 스크롤 구현 하기 (intersection-observer) (0) | 2023.03.24 |
---|---|
React socket.io-client (1) | 2023.03.21 |
REACT-COOKIE / basic (0) | 2023.03.01 |
RESTful API (0) | 2023.02.28 |
TIL - 68 쿠키, 세션, 쿠키-세션, 토큰 (0) | 2023.02.18 |