728x90

타입 추론이란, 

타입을 코드상에 명시적으로 지정하지 않아도 컴파일러가 변수 or 상수의 값을 자동으로 추론해주는 것을 말한다. 

 

예를 들어서, 

const x = 22;

const y = 10;

const z = x+ y ;

일때 컴파일러는 z의 타입이 number임을 자동으로 추론한다.

 

재할당이 가능한 let의 경우에는,

 

let MyName = "Ann";

MyName = 223; //MyName의 타입을 string으로 추론중이므로 에러 발생!

 

이것은 함수의 리턴값이나 객체의 타입을 추론하는 경우에도 동일하다. 

 

그러나 const와 let의 타입 추론 방식은 조금 다르다. 

 

상수인 const 는 리터럴 타입, 변수인 let은 원시 타입 추론이 이루어진다. 

 

여기서 리터럴 타입이란, string, number 와 같이 넓은 의미의 타입이 아니라, 

const x = 30의 경우 x는 30 이라는 구체적인 리터럴 타입으로 추론되는것을 말한다.  

 

원시타입은 우리가 일반적으로 아는 string, number, boolean, undefined 등 포괄적으로 사용되는 타입을 말한다. 

 

 

재할당이 가능한 let은 넓은 범위의 원시 타입으로 추론되지만. 재할당이 불가능한 상수 const는 리터럴 타입으로 추론되는 것이다. 

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/340213?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

처음에는 이렇게 풀었다. 

 

function solution(video_len, pos, op_start, op_end, commands) {
    var answer = '';
    const [min, sec] = pos.split(":").map(Number); 
    const [vmin,vsec]= video_len.split(":").map(Number); 
    const [smin,ssec]=op_start.split(":").map(Number); 
    const [emin,esec]=op_end.split(":").map(Number); 
    let [nmin,nsec] = [min,sec];
    const converter = (min,sec)=>min*60+sec;
    for(cmd of commands){        
        if(cmd==="next"){
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
                nsec += 10;
                if (nsec >= 60) {
                    nsec -= 60;
                    nmin += 1;
                }
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
        }else{
           if (nmin == 0 && nsec < 10) { 
                [nmin,nsec]=[0,0];
            } 
            else if(nsec<10){
                nsec = 60+nsec-10;
                nmin -=1;
            }else nsec = nsec-10;
        }
     
    }
    return nmin.toString().padStart(2, '0')+":"+nsec.toString().padStart(2, '0');
}

 

1,6,7,9,12  총 5개의 케이스에서 틀렸다고 나왔다. 

 

어떤 케이스가 고려되지 않았는지 모르겠어서 질문 게시판을 찾아보니

동영상 길이보다 길어지는 경우를 고려해야 한다고 나와있었다!!!

 

애초에 props로 동영상 길이를 왜 제공해주는지 생각했어야 했는데....ㅎㅎ 나의 실수 

 

그래서 중간에 

 if(converter(vmin,vsec)<=converter(nmin,nsec)) [nmin,nsec]=[vmin,vsec];

이 부분을 추가해 주었는데 어라라 아직도 1번케이스가 통과가 되지 않는 것이었다. 

 

다시 찾아보니 prev 명령어의 경우에도 오프닝 구간안에 있으면 오프닝 끝으로 이동해야한다는 것이었다.........헉 

function solution(video_len, pos, op_start, op_end, commands) {
    var answer = '';
    const [min, sec] = pos.split(":").map(Number); 
    const [vmin,vsec]= video_len.split(":").map(Number); 
    const [smin,ssec]=op_start.split(":").map(Number); 
    const [emin,esec]=op_end.split(":").map(Number); 
    let [nmin,nsec] = [min,sec];
    const converter = (min,sec)=>min*60+sec;
    for(cmd of commands){        
        if(cmd==="next"){
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)) 
               [nmin,nsec]=[emin,esec];
            
                nsec += 10;
                if (nsec >= 60) {
                    nsec -= 60;
                    nmin += 1;
                }
            if(converter(vmin,vsec)<=converter(nmin,nsec)) [nmin,nsec]=[vmin,vsec];
            else if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
        }else{
           if (nmin == 0 && nsec < 10) { 
                [nmin,nsec]=[0,0];
            } 
            else if(nsec<10){
                nsec = 60+nsec-10;
                nmin -=1;
            }else nsec = nsec-10;
            
             if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)) 
               [nmin,nsec]=[emin,esec]; //여기 이부분을 추가함 
        }
     
    }
    return nmin.toString().padStart(2, '0')+":"+nsec.toString().padStart(2, '0');
}

 

오프닝 구간인지 확인하는 조건문을 prev 에서도 넣어주니 

간단하게 해결이 되었다. ㅎㅎ 

난이도 1이라 시간제한이 빡센 문제는 아닌 듯 하다 

 

끝 ~.~

728x90

window에서 vscode를 사용할 때 발생하는 에러인데 
윈도우에서만 줄 끝의 문자 포멧이 CRLF로 다르기 때문이다. (맥/리눅스는 LF)
로드가 안 되는 에러는 아니지만 코드를 편집할때 무척 거슬린다. 
 
 
해결법은 
.eslintrc.js 파일 내부 rule 안에 
이렇게 추가하면 해결된다. 

rules: {
 		.
 		.
 		.
    "prettier/prettier": ["error", { "endOfLine": "auto" }] //이 줄을 추가해주자 
  },

 
 
매우 간단 ~.~ 

728x90

최근 다시 면접을 보러다니면서 

풀스택으로 전환할 생각은 없나요? 왜 프론트엔드를 선택했나요 라는 질문을 많이 받았다.  

 

지금은 내 연차가 길지 않아 프론트엔드 포지션을 고수할 수 있지만, 계속 일을 하고 시니어급이 되었을때

과연 프론트엔드 하나만으로 경쟁력을 유지하기는 어렵지 않을까? 라는 생각이 들었다. 

나의 경쟁력을 높이고, 또 나의 미래의 선택지를 넓히기 위해서는 프론트 뿐만 아니라 백엔드쪽의 역량도 키워야한다는 결심이 섰다. 

 

 

처음 타입스크립트를 공부할 때 nest.js 를 조금 써봤지만, 그 이후로 프론트엔드 개발자로 일하면서 백엔드개발을 경험할 기회가 거의 없었다. 마침 시간도 많이 생겼으니 지금이 백엔드 공부를 할 수 있는 적기가 아닐까? ^^...

 

 

 

node.js나 express는 미들웨어 서버를 구성해보면서 조금 써봤는데 아무래도 너무 제약이 없다보니 나에게는 더 불편하게 느껴졌다.

예를들면, 로컬에서는 잘 돌아가지만 실제로 빌드를 할 때는 예상치 못한 오류들이 발생한다던가...

 

 

그래서 제약사항이 많고 구조적으로 node.js를 사용할 수 있는 프레임워크인 nest.js를 다시 선택했다 

 

https://nestjs.com/

 

NestJS - A progressive Node.js framework

NestJS is a framework for building efficient, scalable Node.js web applications. It uses modern JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Progr

nestjs.com

 

오늘부터 강의도 조금씩 들어보면서 놓고있던 백엔드 개발 감각을 되찾아야겠다. ~,~ 

728x90

나는 주로 업무를 할 때 styled-component와 emotion을 사용해 컴포넌트들을 관리해왔다. 

props를 넘겨줄 수 있어서 동적인 스타일을 적용하기 편리하고, 러닝커브가 낮아서 쉽게 접할 수 있었기 때문이다. 

 

그러나 최근들어 tailwind css를 쓰는 기업들이 많아지면서, 과연 어떤 부분이 css in js 보다 더 좋은지, 혹은 단점은 없는지 알고싶어졌다. ~,~ 

 

 

tailwind 사용방법은 공식 문서를 참고하자 

 

https://tailwindcss.com/docs/installation

 

Installation - Tailwind CSS

The simplest and fastest way to get up and running with Tailwind CSS from scratch is with the Tailwind CLI tool.

tailwindcss.com

 

 

아래에 내가 알게된 둘의 장단점과 차이에 대해 정리해보겠다. 

 

  • CSS in JS 
    • javascript 파일 내에서 스타일을 정의해서 사용한다. 대표적으로 Styled-component, Emotion이 있다. 
    • styled의 경우 const MyComponent = styled.div`...`; 태그를 변수 형태로 정의해서 사용한다.
    • emotion의 경우 const MyStyle = css``;  => <div css={MyStyle}/> css를 변수로 정의해서 css라는 속성으로 넣어준다.
    • props,state에 따라 간단하게 동적인 스타일을 적용할 수 있다. 
    • 러닝커브가 낮아서 쉽게 사용할 수 있다. 
    • 랜더링 시 javascript 파일 안에 style 태그로 들어간다. 
    • js 코드가 업데이트될때마다 함깨 렌더링 되기 때문에 랜더링 속도가 더 오래걸릴 수 있다. (일부 스타일은 브라우저에서 캐싱되기도 함)

 

 

  • Tailwind CSS
    • 랜더링 시 단일 css파일로 동작해 js 코드의 리랜더링 등에 영항을 받지 않는다. html에서 직접 css를 참조. 
    • 정적 css파일로 동작하기때문에 동적인 스타일을 적용하기위해서는 여러 클래스를 조건에따라 관리해야하는 불편함이 있다. (불가능한것은 아님! classnames 로 조건에 따른 복수의 클래스네임을 관리할 수 있다.)
    • 클래스기반의 캐싱을 사용 class name 안에 <a href="#" class="text-blue-500">+ 198 others</a> 기본적으로 제공하는 스타일을 넣거나,
    • 이렇게 커스텀 스타일을 정의해서 사용하는 것도 가능하다.  
module.exports = {
  theme: {
    colors: {
      'blue': '#1fb6ff',
      'pink': '#ff49db',
      'orange': '#ff7849',
    },
  }
}
------------------------------------------------
<div class="bg-blue text-orange p-4">
  custom text
</div>

   

 

우선 기본적으로 tailwind에서 제공하는 유틸리티 클래스 구조와 rem 단위에 익숙해질 필요가 있겠군... 

 

e.g ) className-"p-4" 는 위아래좌우에 1rem(보통 16px)의 패딩을 넣는다는 뜻,

        className="py-2.5 px-3"은 위아래 10px, 좌우 12px의 패딩을 넣는다는 뜻. 

 

       (1: 0.25rem  ==  4px)

728x90

+ Recent posts