프론트엔드 데브코스 5기 TIL 35 - TS모듈, 가져오기, tsconfig, 내장 유틸리티 타입, 특강(TS)

김영현·2023년 11월 14일
0

TIL

목록 보기
42/129

모듈 타입 선언 1

모듈 가져와서 사용할 때 타입을 선언해주어야함.
예를들어 lodash라는 라이브러리를 사용할때. lodash.d.ts파일을 만들어주어야 한다.

//lodash.d.ts
declare module 'lodash' {
	interface Lodash{
    	camelCase(str: string): string,
      	uniq<T>(arr: T[]): T[], // 타입추론
      	cloneDeep<T>(arg: T): T
    }
  	const lodash: Lodash;
  	export default lodash;
};

//main. ts
import lodash from 'lodash';

const str = "aaasaddsd asdvc";
const newStr = lodash.camelCase(str);

const nums = [1,2,3,3,4,4];
const newNums = lodash.uniq(nums);

const obj = {
	a: {x: 1},
  	b: [7, 8]
}
const newObj = lodash.cloneDeep(obj);

메소드를 쓰면 쓸수록 작성해야할 타입선언이 많아진다. 누군가가 만들어놓은 타입선언을 갖다써보자!
없으면...만들어야겠지...?😫

npm info @types/lodash로 누군가가 만들어놓은 타입이 존재하는지 체크할 수 있다.
그다음 npm i @types/lodash -D로 설치!
이후 tsconfig에서 수정해줘야함

//tsconfig.json

"compilerOptions":{
	....
    "typeRoots":["node_modules/@types"]
}

요래 수정해주면 노드모듈에 깔린 타입선언들을 활용할 수 있음.
다만 import lodash from 'lodash';이렇게 사용할수가 없다. export default가아닌 export기 때문

import * as lodash from 'lodash'

//or

//tsconfig.json
"compilerOptions":{
	....
    "esModuleInterop": true
}
//위와같이 작성하면 아래와 같이 편하게 사용 가능
import lodash from 'lodash'

참고로 npm에 들어가면 ts로 작성되어있는 라이브러리를 확인해볼 수 있다!
안되어있다면...ㅎㅎ


모듈타입선언 2

js로 만든 파일을 ts로 가져오게 만들고싶다.

//tsconfig.json
"compilerOptions":{
	....
    "allowJs":true,
}

JS파일 쓸수있게 설정해두면, js로만든 파일을 가져올 수 있다.
이때 JS의 모든 타입은 any가 된다.
=> TS를 쓰는 의미 상실. 해결해보자

//myUtils.js
export const add = (a,b) => a+b;
export const subtract = (a,b) => a-b;
export default { add, subtract };

//myUtils.d.ts 
//이름이 js파일과 같아야함. 다르다면 tsconfig.json의 compilerOptions - paths에 경로별칭을 적어준 뒤, 별칭을 import해주면 된다.
interface DefaultExport{
	add: (a:number, b:number): number,
  	subtract: (a:number, b:number): number
};
declare const de: DefualtExport;
export default de;

//tsconfig.json
...
"include":[
	"src/**/*.ts",
  	"js/**/*.ts",
]

//main.ts
import { add, subtract } from "../js/myUtils.js";

const a = add(4,null); // 타입에러. js였다면 타입에러 없이 진행됨
const c = subtract(9,3); // 6

타입 가져오기&내보내기

ts파일 가져올땐 기본적으로 확장자를 쓰지 않는다.

//myUtils.ts
export interface Add{
	add: (a:number, b:number): number,
};

//main.ts
import { Add } from './myUtils'

const newAdd: Add = (x,y) => x+y

default로 내보내고 싶다면..

//myUtils.ts
export namespace Utils{
	//...add와 subtract에 대한 interface 내용
}
const add: Utils.Add = (a,b) => a+b;
const subtract: Utils.Subtract = (a,b) => a-b;
export default{
	name: 'My utils',
  	add
  	subtract
};

//main.ts
import utils from './myUtils';
import type { Utils } from "./myUtils"

const add: Utils.Add = (x,y) => x+y;

tsconfig.json 파헤치기

자세한건 공식문서에 나와있다.

  • include: 포함(우선순위 낮음)
  • exclude: 제외(우선순위 보통)
  • files: 포함(우선순위 높음)

exclude를 제외한 모든 파일이 ts > js 컴파일됨

  • extends: 다른 tsconfig파일을 확장하여 사용
    참고로 tsc명령어에 적용된 config들을 보려면 --showConfig키워드를 뒤에 추가해주면 된다.
  • strict: 엄격한 타입검사 활성화
    1. 암시적 any타입 불가
    2. 암시적 this타입 불가
    3. 엄격한 null, undefined 타입 검사
    4. 엄격한 매개변수 검사
    5. 엄격한 클래스 속성초기화 검사
    6. 엄격한 bind, call, apply 메소드 인수 검사.
    엄격하구먼?
  • target: ts > js변환할때 JS버전 명시
  • lib: 컴파일에서 사용할 라이브러리 지정(js내부 라이브러리)
  • module: 사용할 모듈 방식 지정
  • moduleResolution: 컴파일러가 사용할 모듈 해석 방식(node, bundler 등) es5이상에서만 bundler 추천
  • paths: 위에서 설명했던 경로 별칭
  • jsx: jsx의 출력방식 제어. 리액트와 같이 사용할때!
  • outDir: 컴파일된 js의 파일 저장위치 설정

내장 유틸리티 타입

//Partial => 필수 속성을 선택 속성으로 바꿔줌
interface User{
	name: string,
  	age: number
}
const userA: User = {
	name:"A", // age가 없어서 에러
}
//제네릭으로 사용
const userB: Partial<User> = {
	name:"A"
}

//Required => 선택 속성을 필수 속성으로 바꿔줌. Partial과 정확히 반대여서 생략

//ReadOnly => 읽기전용. 할당,삭제불가 만들어줌

//Record<Key, Type>
type Nmaes = "neo" | "lewis"
type RecordNames = {
	neo: number,
  	lewis: number
}
const developers: Record<Names, number> = {
	neo: 12,
  	lewis: 13
}

//Pick<타입, 가져올 타입들> => 주어진 객체타입에서 원하는 속성만 가져와서 새로운 객체타입 반환
interface User{
	name: string,
  	age: number,
  	email:string,
  	isValid: boolean
}
interface PickUser{
	name: string,
  	email: string,
}
const user: Pick<User, 'name' | 'email'> = {
	name: "Neo",
  	email: "aaa@aaa.aaa"
}

//Omit => Pick과 정확히 반대여서 생략

//Exclude<Types, Type> => Types에서 특정 Type을 제외한 타입만 허용
type T = string | number | boolean;

const a: Exclude<T, number> = 'Only string';
const b: Exclude<T, number> = 1234;

//Extract => Exclude와 정확히 반대여서 생략

//ReturnType<type> => 반환한 type으로 구성된 타입을 할당
function hello(msg: string){
	return `Hello ${msg}`;
}
const a: ReturnType<typeof hello> = "hi";
                    
//Awaited => 반환된 데이터의 데이터타입으로 할당
const img = getImg(src);
const el = Awaited<typeof img> | null = document.querySelector('photo');

특강

vite

vitewebpack을 대신하는 최신 번들러!
CRA대신 사용할수도 있다.

tsconfig.json 옵션 더

강의에 다루지 않았던 tsconfig.json의 옵션들을 더 알아보겠습니다!

  • removeComments : 주석을 제거할 건지 말지 결정
  • noEmit : 컴파일러 출력으로 JS등 파일,폴더 생성 방지(Babel같은 도구 사용하는 경우 필요할 수 있음)
  • allowImportingTsExtensions : ts확장자 명시 허용.
  • isolatedModules : 각 파일을 독립된 모듈로 처리하도록 강제
  • resolveJsonModule : JSON파일을 ES6모듈로서 가져와 사용할 수 있음(가져와서 타입추론 할수있게).
    moduleResolution의 값이 node16, nodenext, bundler인경우에만 사용 가능하다!
  • useDefineForClassFields : Obect.defineProperty를 사용해 클래스필드를 정의하게 만듬.
    원래 this.a = a로 할당함
  • noUnusedLocals : 사용하지 않는 지역변수에 대해 컴파일러가 오류를 발생시킴.
  • noUnusedParametes : 사용하지 않는 매개변수에 대해 컴파일러가 오류를 발생시킴.
  • noFallthroughCasesInSwitch : switch문 내부 break없을때 오류발생
  • skipLibCheck : 선언 파일의 타입검사를 건너뜀!
  • baseUrl : 모듈 해석에 사용할 기준경로를 지정. 보통 paths옵션과 같이 사용함
  • allowJs : .js, .jsx파일 입력 컴파일러 허용.(ts 마이그레이션 할때 js랑ts가 공존하기위해 보통 사용)
  • checkJs : .js, .jsx 파일의 타입 검사를 수행함. (JSDoc 주석을 사용해 타입 선언할 수 있음. 이 역시 마이그레이션용...)
//JSDoc은 이렇게 사용한다.

/**
*	@param { number } a
*	@param { number } b
*	@returns number
*/
export const hello = (a,b) => a + b 

JSDoc은 API문서를 만들때 용이함!!

  • types : 컴파일러가 참조할 (@types)패키지 목록을 명시적으로 제한
  • satisfies : 타입 단언을 보다 안전하게 사용할 수 있게해줌
interface User{
	name: string,
  	age: number
}
//안전하지 않은 타입 단언
const userB: User = {
	name:"kim"
} as User
//안전한 타입 선언
const userB: User = {
  //에러남
	name:"kim"
} 
//안전한 타입 단언(만족)
const userB: User = {
  //에러남
	name:"kim"
} satisfies User

// as는  안전하지 않다. 하지만 satisfies는 타입을 완벽히 만족해야함.
const userD = {
	info:{
    	name: 'neo',
      	age:95,
      	isValid: true,
    } satisfies User
}

js => ts 마그레이션 방법

js클래스, 내부 메소드에 JSDoc작성하고 천천히 TS로 옮긴다!


느낀점

TS는 언뜻보면 쉽지만 실제로 적용하려면 애 먹는 종류일 것 같다.
토이프로젝트에 꼭 적용해봐야지...!!! 간단한 투두리스트라도 만들어봐야겠음.
마이그레이션도 언젠간 도전해보고싶지만 시간이...😥

profile
모르는 것을 모른다고 하기

0개의 댓글