[TypeScript] interface와 type 비교(인터페이스, 타입 별칭) 그리고 변경 불가능한 interface와 type 만들기

이미지
Interface 와 type의 차이 1번. 확장 방식 interface(인터페이스)와 type(타입 별칭)의 가장 큰 차이점은 extends 키워드로 타입의 확장이 가능하냐 불가능하냐 이다.  interface(인터페이스)는 extends로 확장이 가능하지만 type(타입 별칭)은 확장이 불가능하다. extends로만 확장이 불가능할 뿐 type 또한 아래와 같은 방식으로 확장이 가능하긴하다. ex) type test1 = {name: string} type test2 = test1 & {age: number} const test3: test2 = { name: 'd', age: 33 } extends로 확장이 필요한 경우가 많기 때문에 interface를 사용하는것이 좋다. 추가적으로  interface의 경우 다른곳에서 동일한 이름의 interface를 정의하게되면 동일한 명칭의 interface를 하나의 interface로 합친다. 그래서 특정 라이브러리에 내가 원하는 타입을 추가하거나 확장할 때 d.ts 파일에서 interface로 정의하면 해당 라이브러리에 선언된 interface 와 내가 추가적으로 작성한 interface가 합쳐진다.  반면에 type을 사용하여 동일한 이름으로 다른곳에서 type을 정의하게되는  경우에는 에러가 발생한다. 2번. 상세 타입 정보 제공 아래 사진과 같이 interface는 상세 타입정보가 나오지 않지만 type의 경우 상세 타입정보가 나온다. 하지만 interface를 사용하더라도 해당 interface를  cmd + 클릭하면 interface가 정의된 곳으로 바로 가서 타입을 확인할 수 있다. interface (인터페이스) type (타입 별칭) 3번 interface 는 객체를 정의하는것이고, type 은 타입과 객체를 두개를 모두 정의할 수 있다. interface RSP { ROCK : string ; SISSORS : string ; PAPER : string ;

[Firebase] auth 소셜(Social) 로그인 설정하기

이미지
1번. Firebase 콘솔(console)로 이동한다. 아래와 같이 메뉴를 클릭하면 해당 로그인을 제공해줄 업체에서 제공하는  Client ID( 클라이언트 ID) 와  Client secrets(클라이언트 보안 비밀번호)가 필요한것을 확인할 수 있다. 구글 로그인의 경우 Firbase가 구글것이기 때문에 따로 설정할 필요는 없다. github 로그인을 예로 들어보았다. 2번. github에 와서 Settings ---> 메뉴바에 Developer settings ---> OAuth Apps 클릭 ---> New OAuth App 클릭 3번. New OAuth App으로 설정하고나면 위에서와 같이 login-auth가 생긴것을 확인할 수 있다. 해당 App을 클릭해보면 아래와같이 화면이 나온다. 빨간색 네모박스안에 있는 Client ID와 Client secrets 를 Firebase로 돌아가서 입력하면 된다.

[JavaScript] null 병합 연산자 (??) - (nullish coalescing operator)

null 병합 연산자 (??) 를 사용하면 여러 피연산자 중 확정 되어있는 변수를 찾을 수 있다. 확정되어있는 변수라는 말은 정의된 값을 말한다. 즉, null과 undefined 값이 아닌 모든 값을 true로 인식한다는것이다. null 병합 연산자를 사용하는 이유 const age = 45 ; const userAge = age || "secret" ; console . log ( userAge ); // 45 const num = null ; const count = num || "undefined" ; console . log ( count ); // undefined 위 예제와 같이 or 연산자를 사용하여 코드를 많이 작성한다. 앞에 값이 false이면 뒤에 값을 반환하고, 앞에 값이 true이면 뒤에 값을 반환한다. 하지만 여기서 문제점이 발생한다. 일반적으로 false로 인식되는값들은 아래와 같다. false, '', 0, null, undefined 이러한 false로 인식되는 값들이 상황에 따라 문제를 발생시킨다. 상황에따라 사용자에게 값을 받을때 0을 받거나 ' ' 공백을 받을 수 있다. 그런데 이러한 경우에도 false로 인식되어 원하는 방식대로 코드가 동작하지 못하게된다. 아래에 예시로 문제점을 확인해보자. // ex1) 애기의 나이를 사용자로부터 받아올 떼 const babyAge = "" ; const userAge = babyAge || "secret" ; console . log ( userAge ); // secret // ex2) 물 섭취 횟수를 사용자로부터 받아올 떄 const drinkCount = 0 ; const totalCount = drinkCount || "undefined" ; console . log ( count ); // undefined or 연산자를 사용

Node.js 에서 xml 데이터 파싱하여 json 형태로 변환하기

공공데이터 포털에서 OPEN API를 제공받아 사용해보려고 하면 일반적으로 JSON, XML 형식으로 데이터를 제공한다. 하지만 모든 OPEN API에 해당하는것은 아니며 XML 형식만 제공하는 OPEN API들이 있었다. 내가 사용하고자하는 OPEN API가 XML 형식으로만 지원했고 이러한 XML 형식의 데이터들을 JSON으로 바꾸어 사용하고 싶었다. 찾아보니 xml을 json으로 변경시켜주는 xml-js 라는 라이브러리가 있었다. https://www.npmjs.com/package/xml-js $ npm install xml-js request 예제 소스코드는 아래와 같다. const convert = require ( " xml-js " ) ; const request = require ( " request " ) ; const END_POINT = " http://apis.data.go.kr/B552584/EvCharger " ; const SERVICE_KEY = " 일반 인증키(Encoding) " ; const requestUrl = `${ END_POINT } /getChargerInfo?serviceKey= ${ SERVICE_KEY } &numOfRows=10&pageNo=1 ` ; request . get (requestUrl, ( err, res, body ) => { if (err) { console . log ( ` err => ${ err }` ) ; } else { if (res . statusCode === 200 ) { const result = body ; console . log ( ` body data => ${ result }` ) ; const xmlToJson = convert . xml2json (result, { com

[CSS] 반응형 이미지, 비디오 (or 가변 이미지, 비디오)

이미지의 경우 웹 문서에 삽입할 때부터 이미지의 크기가 정해져 있기 때문에 브라우저 창의 크기가 변화한다 하더라도 이미지킈 크기 값은 바뀌지 않는다. 그래서 브라우저 화면의 크기가 줄어들면 이미지의 일부가 가려지는 현상이 발생한다. 이러한 문제점을 해결하기 위해서 CSS를 이용하거나 <img> 태그의 srcset 속성을 이용하여 문제를 해결할 수 있다. 그 외에도  <picture> 태그와 <source> 태그를 사용할 수 도 있다. CSS를 이용한 방법 이미지를 변경되는 레이아웃에 맞게 표시하려면 이미지를 감싸고 있는 부모 요소 만큼 커지거나 작아지도록 하면되는데 이때 { max-width: 100%; height: auto; } 를 속성값으로 지정해 주면 된다. max-width 가 아닌 width 속성을 사용해도 된다. <img> 태그의 srcset 속성을 이용하는 방법 <img> 태그의 srcset 속성은 가각의 다른 환경에서 사용될 이미지 소스를 명시한다. css의 { max-width: 100%; height: auto; } 속성을 이용하더라도 모든 상황에서 사용할 수 있는것은 아니다. 고해상도의 이미지의 경우 크기가 줄더라도 파일의 용량은 크기 때문에 모바일에서 다운로드하는데 시간이 오래 걸릴 수 있다.  또한 텍스트가 포함된 이미지일 경우 모바일 화면에 맞게 줄여 표시하면 텍스트가 너무 작아져 내용을 알아보기 힘들어진다. 이때 <img> 태그의 srcset 속성을 이용하면 화면 너비 값이나 픽셀 밀도에 따라 이미지 파일을 지정할 수 있다. < img srcset = "img1-320w.png 320w, img2-480w.png 480w, img3-800w.png 800w" sizes = "(max-width: 320px) 280px, (max-width: 480px) 440

크로스 도메인 CORS 에러 문제 해결(공공 데이터 포털)

이미지
프론트단에서 공공데이터 포털에서 제공해주는 OPEN API를 바로 요청해서 사용하려고했는데 해당 오류가 발생했다. API KEY만 삭제한 오류  내용: Access to XMLHttpRequest at 'http://apis.data.go.kr/B552584/EvCharger/getChargerInfo?serviceKey=${API KEY}&numOfRows=5&pageNo=1' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 자바스크립트의 표준 스펙에는 다른 출처(서버)로의 요청을 허용하지 않는 동일 출처 정책(Same Origin Policy)이 있다. 도메인, 서브도메인, 프로토콜, 포트가 다른 곳에서 요청을 보내는경우 발생한다. 브라우저에서 다른 서버에 요청할 경우 해당 정책이 적용되지만 브라우저를 거치지않고 서버간의 통신에서는 해당 정책이 적용되지 않는다. 사진으로 간단히 그려봤다. 찾아낸 해결방법이 Node.js로 서버 통신을 통해 API 데이터를 받을 수 있다는 것이었다. 다행히도 Node.js를 공부했었어서 데이터를 받아오는데는 쉬웠지만 JSON이 아닌 XML 데이터를 제공해주기 때문에 변환이 필요했다. 이부분은 라이브러리를 사용해서 변환할 수 있었다.

[Error] signInWithPopup failed: First argument "authProvider" must be a valid Auth provider.

이미지
Material UI와 React를 함께 사용할때 해당 오류가 발생하는 경우가 있다. 문제점을 찾아보니 React의 index.js에 작성되어있는 <React.StrictMode>가 문제였다. 해외 커뮤니티를 찾아봐도 다들 말이 다른데 오류가 해결된 방법은 <React.StrictMode> 를 주석처리 시키는것이었다. 외국인들 말로는 Material UI 자체 문제라고 한다.

(CSS-in-JS) styled-components 사용방법, 요약정리

이미지
styled-components는 CSS 파일 없이도 JS 파일 내부에서 CSS를 작성할 수 있도록 도와주는 라이브러리이다. 프로젝트를 진행하면서 CSS와 JS파일을 왔다갔다하는 번거로움을 줄여준다고해서 사용해봤다. styled-components를 사용해보면서 느낀 장점은 아래와 같다. 1. styled-components를 사용하면 한 창에서 디자인, 로직 모든것을 해결할 수 있다. 2. CSS 파일을 추가적으로 생성하지 않아도 된다. 3. SCSS 에서 사용하던 문법을 비슷하게 사용할 수 있다. 4. class 명칭을 고민하는 시간이 줄어든다.? 사용법과 간단하게 공부했던 내용을 정리해보려고 한다. 사용방법 import React from " react " ; import { Link } from " react-router-dom " ; import styled from " styled-components " ; import " ./MenuFont.css " ; // styled-components const List = styled . ul ` display : flex ; list-style : none ; ` ; const Item = styled . li ` padding-right : 1 rem ; ` ; const StyledLink = styled ( Link ) ` text-decoration : none ; color : black ; ` ; const CenterMenu = () => { return ( < List className = " Menu-Font " > < Item > < StyledLink to = " / " > Home </ StyledLink > </ Item