declare에 관한 공부를 하다가
sample.js에서 만든 변수를 index.js에서 가져다 쓰는데 계속해서 변수를 찾을 수 없다고 해서 보니
<script src="index.js"></script>
<script src="sample.js"></script>
어후 브라우저가 위에서 아래로 읽고 자바스크립트 엔진도 위에서 아래로 읽는데.... 저런 위치선정을 해버려서 계속해서 sample
에 있는 변수를 index.js
에서 찾을 수 없다고 했다 ....
역시 자나깨나 위치선정 중요하다.
공식문서도 참고하고 블로그들을 여러 곳을 가보면 declare에 대해서 주로 설명한 것이 있다.
ts파일과 js파일을 섞어서 사용 할 때
js 파일에 있는 것을 ts 파일에서 자동으로 import export 없이 사용 할 수 가 있는데..
아래와 같이 script가 html의 한 곳에 있다면
<script src="data.js"></script>
<script src="index.js"></script> // ts를 컴파일한 js 파일
//data. js
const a = 10;
// index.js
console.log(a+1) // 11이 정상적으로 나온다.
정상적으로 import
, export
없이 사용 할 수 가 있다 .
그런데 ts 파일에서는???
// data.js
const a = 10;
// index.ts
console.log(a+1)
컴파일러가 에러를 띄우는데 여기서 index.js
말고 index.ts
에서 declare 라고 선언 후 a의 타입을 명시하면 오류가 해결 된다 는 이야기 이다.
// data.js
const a = 10;
// index.ts
declare let a : number
console.log(a+1)
cannot find name a 라는 문구가 없어진것을 확인 할수 가 있다.
지금 위와 같은 예시가 와닿고
왜 declare를 선언하는지 아주 미세한 '감'은 잡았지만, 저 감을 갖기까지 해본 실험?, 정보를 종합적으로 써보고자 한다 .
내가 생각한 것 일 뿐 혹시나 오류가 있으면 댓글로 남겨주세요..
우리가 typescript로 코드를 치면 typescript complier가 javascript로 해석하고 그 javascript로 해석된것이 브라우저 상에서 띄게 된다.
굳이 typescript를 사용하는 이유는 type을 명시하여 조금더 인간이 범할 수 있는 오류와 에러, 실수를 줄이고자 함이다.
javascript 대신 typescript를
<script src="index.ts"></script>
로 html에 붙이면 되는것 아닌가 할 수 있지만, 아쉽게도 브라우저는 javascript만 읽을 줄 아는 줏대 있는 녀석이기에...
typescript를 사용하면 반드시 complier로 javascript로 해석해야한다 .
즉,
내가 놀 곳은 어쨌건간에
브라우저가 해석하는 것은
위의 생각을 탑재하고 천천히 다시 한번더 예시를 봐보자.
협업을 하는 과정에서 typescript로만 짜놓은 코드들을 가지고
import
, export
하는 것만 있으면 좋겠지만,
외부 자바스크립트 파일을 이용할 경우를 생각해보자
아직 개발자가 아니라 모르지만
<script src="sample.js"></script>
<script src="index.js"></script> // ts를 컴파일한 js 파일
여기서 중요한 것은
내가 코드를 짜는 파일은 playground는 index.js
가 아니다.
index.ts
이다.
sample.js 에서 변수, 함수등을 만들었을 때 index.js 파일에서는 당연히 import
, export
를 안해도 가져다가 사용 할 수 있겠지만,
물론 export
, import
해서 써도 작동이된다.
// sample.js
const a = 10
// index.js
console.log(a+1) // 11
//export, import
// sample.js
export const a = 10
// index.js
import { a } from "./sample";
console.log(a+1) //11
여기서 index.js에다가 내가 직접 console.log(a+1)
해줬을까??
아니다.
index.ts
에서 내가 console.log(a+1)
을 해준것이 compile이 되어서 index.js
에 꽂힌것이다.
그런데 여기서 한가지 불편한 점이 발생한다 .
index.ts 파일에서 위와 같은 에러가 뜨는 것이다..
내가 index.js에서 play를 한다면 모를까 내가 작업하는 파일은 ts이기에 저러한 문제를 해결해야 하는 것이 타입스크립트를 사용하는데 올바른 방도 일 것이다.
혹시 몰라서 import, export 이런것을 시도해보긴 했다.
// sample.js
export const a = 10;
// index.ts
import {a} from './sample.js' // could not find a declaration file
console.log(a+1)
당연히 안되지... ts파일하고 js 파일 서로 다른 확장파일이니까...
이럴 때 어떻게 한다. ...
이럴 때 사용 할 수 있는 것이
declare
라는 선언 keyword 이다.declare라는 키워드에 관하여 찾아보니
The declare keyword is used to define something with a type without providing a value/implementation for it
간단하게 내가 생각한 요약은
변수에 할당 같은 것 없이 어떠한 변수에 대한 타입을 정의하는데 사용되는 keyword이다 라는 의미인것 같다 .
그러면 여러 declare에 관련한 정의들에 관해서도 조금씩 이해가 되기 시작했다 .
변수, 상수, 함수, 또는 클래스가 어딘가에 이미 선언되어 있음을 알린다.
declare 키워드는 변수의 값을 정의하지 않고 변수의 타입을 지정할 때 사용되는 주변 선언에서 사용되며, 이러한 선언은 TypeScript에 정의된 항목이 코드 어딘가에 존재한다고 알려주는 역할
declare는 코드에 실제로 존재하는 객체나 값의 구현을 정의하는 것이 아니라, 그 존재와 형태만을 TypeScript에 알려주는 역할
이러한 글귀들이 말이다.
어딘가에서 선언하고 할당된 js 파일 (ts파일 말고)에 있는 변수들을 ts 파일에 가져다 사용은 할 수 있지만 - ( 내가 놀곳은 .ts
compile이 되고 브라우저에서 읽는 곳은 .js
파일 )
js 에 있는 변수들 등을 ts에 사용 하는데 있어서 ts compiler에게
" 이 변수는 어딘가에,암튼 어딘가에 있고 이것을 사용 할거임 "
이라고 말해주는것이다.
그렇다면 다시 변수를 재선언해주는 것인데
"그러면 컴파일 되는 js 파일에서도 변수명을 써줄까? , 너무 불필요한것 아닌가" 라는 의문점이 당연히 든다.
declare를 붙인 코드들은 js로 컴파일 되지 않는다.
// sample.js
const a = 10;
// index.ts
declare const a : number;
console.log(a+1)
// index.js
// const a; 라는 변수가 컴파일 되지 않는다.
console.log(a+1)
그러므로 자바스크립트로만 작성된 외부 라이브러리들을 쓸 때
이 declare keyword를 사용하면 될 듯 하다 .
참고)
타입스크립트 버전이 없다면 직접 declare로 타입작성하면 됩니다.
여기서 리액트 같은 프로젝트에서
tsconfig.json
안에 allowJs 옵션을 true로 켜두면
js파일도 타입지정이 알아서 implicit 하게 된다.
리액트 같은 프로젝트에서 유용 하다.
그냥 import, export 하면 되지 굳이 declare를 사용하는 것은 좀 아니지 싶다 .