Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
Tags
- ReactDOM.render is no longer supported in React 18. Use createRoot instead
- JS 개념
- react오류
- 자바스크립트
- Colaboratory 글자 깨짐
- 웹 게임을 만들며 배우는 리액트
- Spring-Framework
- 모던자바스크립트
- DB Browser
- node.js 설치
- 인프런
- 모두의 파이썬
- intllij 내 Bean을 찾지 못해서 발생하는 오류
- intellij
- 거북이 대포 게임
- googleColaboratory
- Do it 자바스크립트 + 제이쿼리 입문
- vs code 내 node
- 계산맞추기 게임
- Python
- react
- spring-boot
- 노드에 리액트 추가하기
- You are importing createRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client"
- 따라하며 배우는 노드 리액트 기본 강의
- props
- 리액트
- 타자 게임 만들기
- Concurrently
- node.js로 로그인하기
Archives
- Today
- Total
프로그래밍 삽질 중
[TS] Axios 타입 분석(get, post, error) 본문
출처 : https://github.com/ZeroCho/ts-all-in-one
* axios
- axios = fetch + 여러가지 기능(XHMLHttpRequest)
- 서버 응답, 요청 시 많이 사용
* axios 사용방법(크게 3가지)
1. new axios();
2. axios(); //함수처럼
3. axios.get()
* import 방식여부 index.d.ts 파일 내용 따라 다름
//index.d.ts 파일 내에서
//마지막 줄에 export defaul axios 같은 게 있는지 찾아보기(가장 중요함)
import axios from 'axios'
// common.js 모듈의 경우
import axios = require('axios')
// common.js 모듈이어도 es.internal인 경우
import * as axios from 'axios'
//(* as 제거 가능)
import axios from 'axios'
[index.d.ts]
export interface AxiosInstance extends Axios { //interface도 무조건 객체가 아니라 함수가 있으면 함수로 가능
(config: AxiosRequestConfig): AxiosPromise; //함수
(url: string, config?: AxiosRequestConfig): AxiosPromise; //함수
}
export interface AxiosStatic extends AxiosInstance { //얘는 객체 => 함수를 객체가 상속받음
create(config?: AxiosRequestConfig): AxiosInstance;
Cancel: CancelStatic;
CancelToken: CancelTokenStatic;
Axios: typeof Axios;
readonly VERSION: string;
isCancel(value: any): boolean;
all<T>(values: Array<T | Promise<T>>): Promise<T[]>;
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
isAxiosError(payload: any): payload is AxiosError;
}
// export interface AxiosStatic extends AxiosInstance 예시
const a = () => {}
//함수 안에 함수.속성으로 또 다른 함수를 넣음
a.create = () => {};
a.isAxiosError = () => {};
a.z = '123';
a();
a.create()
a.isAxiosError()
export class Axios { //클래스면서 함수면서 객체
constructor(config?: AxiosRequestConfig);
defaults: AxiosDefaults;
interceptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>;
response: AxiosInterceptorManager<AxiosResponse>;
};
getUri(config?: AxiosRequestConfig): string;
request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
delete<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
head<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
options<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
put<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
patch<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
postForm<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
putForm<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
patchForm<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
}
//axios.get()
get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
// url이 첫 번째 매개변수
// R(AxiosRespone)
export interface AxiosResponse<T = any, D = any> {
data: T; //데이터의 타입을 T로 넣음
status: number;
statusText: string;
headers: AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
isAxiosError(payload: any): payload is AxiosError;
export class AxiosError<T = unknown, D = any> extends Error {
constructor(
message?: string,
code?: string,
config?: AxiosRequestConfig<D>,
request?: any,
response?: AxiosResponse<T, D>
);
config: AxiosRequestConfig<D>;
code?: string;
request?: any;
response?: AxiosResponse<T, D>;
isAxiosError: boolean;
status?: string;
toJSON: () => object;
static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION";
static readonly ERR_NETWORK = "ERR_NETWORK";
static readonly ERR_DEPRECATED = "ERR_DEPRECATED";
static readonly ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE";
static readonly ERR_BAD_REQUEST = "ERR_BAD_REQUEST";
static readonly ERR_CANCELED = "ERR_CANCELED";
static readonly ECONNABORTED = "ECONNABORTED";
static readonly ETIMEDOUT = "ETIMEDOUT";
}
}
* TS 파일 실행 시 JS로 변환해야 함 => 매번 변경하기 번거로움
npm i -g ts-node //ts-node -g로 설치 시 명령어로 이용 가능
//일반적인 터미널에서 사용하는 경우
ts-node axios.ts
//powershell에서 사용하는 경우
npx ts-node axios.ts
* [Axios.get] 해당 코드는 문제 없는 가?
▶ 실제로 오류는 안 나지만 문제 있는 코드
▶ 왜 문제가 있는가? = 모든 타입이 any로 되어 있음
▶ 주소는 더미데이터 확인하는 API 주소 : https://jsonplaceholder.typicode.com/guide/
(async () => {
try {//현재 모든 타입이 any로 되어 있음
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response.data);
console.log(response.data.userId);
console.log(response.data.id);
console.log(response.data.title);
} catch (error) {}
})();
* [Axios.get] 수정한 코드
import axios from "axios";
//type, interface 둘 중 어느 것으로 해도 상관 없음
type Post = {userId: number, id: number, title: string, body: string}
//interface Post {userId: number, id: number, title: string, body: string}
(async () => {//getResponse, getResponse2 둘 다 상관 없음
try {
// get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
const getResponse = await axios.get<Post>(
"https://jsonplaceholder.typicode.com/posts/1"
);
const getResponse2 = await axios.get<Post, AxiosResponse<Post>>(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response); //const response: AxiosResponse<Post, any>
console.log(response.data.id) //(property) AxiosResponse<Post, any>.data: Post
} catch (error) {}
})();
export interface AxiosResponse<T = any, D = any> {
data: T; //이 코드에서 data는 Post
status: number;
statusText: string;
headers: AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
}
* [Axios.post]
▶ 주로 postResponse를 많이 쓰기 때문에 이 방법으로 진행할 것
//index.d.ts
//post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
//첫 번째 자리는 url, 두 번째 자리는 data(당장 쓰지 않는데 왜 받는지?)
//postResponse에서는 data 타입 D는 당장 쓰지 않으나 postResponse2에서는 data 타입 D를 받음
const postResponse = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
})
const postResponse2 = await axios({
method: "post",
url: "https://jsonplaceholder.typicode.com/posts",
data: {
title: 'foo',
body: 'bar',
userId: 1,
}
})
* [Axios.post] type이 붙을 경우
▶ Created : AxiosResponse<T>에서 T, post 요청에 대한 응답의 데이터 타입
▶ axios.post 설명 (출처 : https://velog.io/@richard/project)
import axios, {Axios, AxiosResponse} from "axios";
interface Post {userId: number, id: number, title: string, body: string}
interface Created {} //post 요청에 대한 응답의 데이터 타입
interface Data {title: string, body: string, userId: 1}
(async () => {
try {//현재 모든 타입이 any로 되어 있음
const response = await axios.get<Post, AxiosResponse<Post>>(
"https://jsonplaceholder.typicode.com/posts/1"
);
// post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
const response2 = await axios.post<Created, AxiosResponse<Created>, Data>('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
})
console.log(response2) //const response2: AxiosResponse<Created, any>
} catch (error) {}
})();
* Axios Error 처리 방법
* 참고 : https://ba-gotocode131.tistory.com/219?category=987174
▶ 타입가드 사용
import axios, {Axios, AxiosError, AxiosResponse} from "axios";
interface Post {userId: number, id: number, title: string, body: string}
interface Created {}
interface Data {title: string, body: string, userId: 1}
(async () => {
try {
...
})
} catch (error) {
// isAxiosError(payload: any): payload is AxiosError;
if(axios.isAxiosError(error)) { //커스텀 타입가드
console.error(error.response?.data)
}
}
})();
* (오류) Axios Error 처리 방법 : 메세지를 넣고 싶다면?
▶ 제네릭으로 message를 넣어도 console.error에서 기억하지 못함
import axios, {Axios, AxiosError, AxiosResponse} from "axios";
interface Post {userId: number, id: number, title: string, body: string}
interface Created {}
interface Data {title: string, body: string, userId: 1}
(async () => {
try {
...
})
} catch (error) {
if(error instanceof AxiosError<{message: string}>) {
//{message: "서버 장애입니다. 다시 시도해주세요"}
console.error(error.response?.data.message) //response가 여전히 any가 나옴
}
}
})();
* (해결법) Axios Error 처리 방법 : AxiosResponse 이용
import axios, {Axios, AxiosError, AxiosResponse} from "axios";
interface Post {userId: number, id: number, title: string, body: string}
interface Created {}
interface Data {title: string, body: string, userId: 1}
(async () => {
try {
...
})
} catch (error) {
if(axios.isAxiosError(error)) {
//{message: "서버 장애입니다. 다시 시도해주세요"}
console.error((error.response as AxiosResponse<{message: string}>)?.data.message)
//(property) AxiosResponse<{ message: string; }, any>.data: {message: string;}
}
}
})();
export interface AxiosResponse<T = any, D = any> {
data: T;
status: number;
statusText: string;
headers: AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
}
'과거 프로그래밍 자료들 > Javascript&typescript' 카테고리의 다른 글
[TS] Axios 타입 분석 및 Axios 타입 만들기(get, post, put, patch, delete) (1) | 2022.09.21 |
---|---|
[TS] flat (1) | 2022.09.20 |
[TS] bind (1) | 2022.09.20 |
[TS] Promise, Awaited (1) | 2022.09.20 |
[TS] (utility types) infer 타입 분석 (0) | 2022.09.20 |