TypeScript 기초

GGAE99·2023년 5월 10일
0

자바스크립트 & 타입스크립트

자바스크립트(JS)

동적 타입 언어로 런타임에서 동작할 때 타입 오류를 확인할 수 있다.

타입스크립트(TS)

정적 타입 언어로 코드 작성 단계에서 타입 오류를 확인할 수 있다.
타입을 엄격하게 다루기 때문에 타입스크립트인 것 같다.

타입스크립트 타입 종류

문자열 : string
숫자 : nunber
불린 : boolean
null / undefined
배열 : type []
객체 : object (하지만 interface를 더 애용한다.)
함수 : function
Any : any ( 아무거나 할당해도 괜찮은 타입)
Unknown : unknown ( 어떤 값이 할당될지 모르는 타입 | any와는 다름)
튜플 : Tuple []
Void : void

const abc : any = 1; //변수 선언

위와 같은 타입들이 존재한다. 전부는 아닐지도 모른다...

타입스크립트 특징

타입 추론

1) 초기화된 변수
2) 기본값이 설정된 매개 변수
3) 변환 값이 있는 함수

위의 3가지 요소를 근거로 타입을 추론하고 할당한다.

let num = 12;
num = 'Hello type'; //에러 -> num에 12를 초기화함으로서 이미 num은 number타임으로 추론

//기본값이 지정된 매개 변수 'b' + 반환 값이 확실한 함수 'add'
function add1(a: number, b: number = 2) {
    return a + b;
}

타입 할당

as 키워드

const el = document.querySelector('body') as HTMLBodyElement;
el.textContent = 'Hello World!'; 

body 태그가 없을 경우에 el에 할당되는 값은 null이기 때문에 el.textContent가 에러를 범하는데, el 태그를 가져오고 as HTMLBodyElement를 선언해 주었기에 컴퓨터를 안심시켜줌
(null 안가져오겠구나~ HTMLBody요소구나~)

! 키워드

let num1!: number //값을 할당했다고 단언 (!)
console.log(num1); //

typeGaurd

function logText(bl: Element){
    console.log(bl.textContent);
}
const h1E1 = document.querySelector('h1');
// instanceof = 설정한 조건에 맞는 타입의 변수일 경우 실행
if(h1E1 instanceof HTMLHeadingElement){ // h1E1에 null값을 넣는것을 방지하는 타입 가드 
    logText(h1E1);
}

function add(val: number){
    let res = 'Result => '
    if(typeof val === 'number'){ //if문을 사용하여 typeGaurd
        res += val.toFixed(2);
    }
}
add(3.141592);

인터페이스

선택적 속성 - ?
읽기 전용 - readonly

interface User {
    name: string
    readonly age: number //객체의 속성을 수정할 수 없도록 막음
    isValid?: boolean  //isValid가 있어도되고 없어도 된다는 뜻
    getName: GetName
}

인덱스 시그니처
객체의 특정 value에 접근할 때 그 value의 key를 문자열로 인덱싱해 참조하는 방법
<key, vlaue>형식이며 key와 value의 타입을 정확하게 명시해야하는 경우 사용할 수 있다.

interface User2 {
    [key: string]: unknown; //인덱스 설정
    name: string
}
const heropy2: User2 = {
    name: 'heropy' //name값만 할당
}
heropy2['isValid'] = true; // isValid를 key로 값은 true

타입 별칭

평범한 타입은 별칭을 사용하지 않고, 주로 union타입을 명시하는데 쓴다.

type TypeA = string;
type TypeB = string | number | number;

클래스

접근 제어자
public - 어디서나 자유롭게 접근 가능, 클래스 바디에서 생략 가능
protected - 나와 파생된 후손 클래스 내에서 접근 가능
private = 내 클래스에서만 접근 가능

//클래스 선언의 기본
class UserA{
    constructor(
        public first: string = '', 
        public last: string = '', 
        public age: number = 0
    ){
    }
    getAgee(){
        return `${this.first} ${this.last} is ${this.age}` ;
    }
}

제네릭

제네릭이란 타입을 마치 함수의 파라미터처럼 사용하는 것을 의미한다.
함수 제네릭

function toArray<T>(a: T, b: T){ ..타입을 받도록 함수 설정
    return [a,b];
}

console.log(
    toArray<string>('foo', 'bar'), //타입을 정확히 명시하거나, 받는 매개변수의 타입으로 T 결정
    toArray(1, 2),
    toArray(true, false),
    toArray({x:1}, {x:2}),
    toArray([1,2],[3,4,6]) //number[] 배열로 인식함
);

클래스 제네릭

class UserG<P> { //타입을 받도록 클래스 설정
    constructor(public payload :P){}
    getPayload(){
        return this.payload;
    }
}
interface UserGAType{
    name: string,
    age: number,
    isValied: boolean
}
const gc1 = new UserG<UserGAType>({ //UserGAType을 타입으로 사용
    name : 'gc1',
    age: 59,
    isValied: true,
    //emails: [] // ?! //타입에 eamil이 없어서 에러
})

인터페이스, 제약조건 제네릭

interface MyData<T extends string | number> { 타입을 string 또는 number만 받도록 설정
    name: string
    value: T
}
const dataA: MyData<string> = {
    name: 'dataA',
    value: 'dataA'
}
const dataB: MyData<number> = {
    name: 'dataB',
    value: 10
}
/* const dataC: MyData<boolean> = { //boolean이라 에러
    name: 'dataC',
    value: true
} 

패키지

import _ from 'lodash';

const str = 'the some string'

console.log(_.camelCase(str));
console.log(_.snakeCase(str));

npm info @types/modulename - 모듈 있는지 확인
npm i @types/modulename -D 개발 환경에 의존성을 부여하여 설치

자바스크립트를 타입스크립트로 변경하도록 설정

declare module 'lodash' {
    interface Lodash{
        camelCase: (str: string) => string;
        snakeCase: (str: string) => string;
    }
    const _: Lodash;
    export default _;
} 

tsconfig.json

하나하나 정리하기보다 전체 구조를 보는게 더 좋을 것 같아서 코드 전체를 올린다.

{
    //컴파일러 옵션 지정
    "compilerOptions": {        
        //컴파일될 ES(JS) 버전 명시 -> 2015년도 버전으로 ts를 js로 변환
        "target": "ES2015",
        //자바스크립트의 표준 명칭 -> 최신 버전으로 사용하겠다 / CommonJS에서 ESNext로 변경함
        "module": "ESNext",
        // 모듈의 해석 방식 지정 / 특정 경로의 index js 파일 생략 가능
        "moduleResolution": "Node",
        // ESM 방식 활성화 여부/ CommonJS 방식 모두 사용
        "esModuleInterop": true,
        // 모든 파일을 모듈로 컴파일, import 혹은 export 키워드 필수 / 모든 파일은 모듈이어야만 하는 옵션
        "isolatedModules": true,
        //코드 컴파일시 내부적으로 사용해야하는 라이브러리 목록
        "lib": ["ESNext", "DOM"],
        //문법을 엄격하게
        "strict": true,
        // 데이터 타입마다 strict를 적용할 수 있음
        // 모듈 해석에 사용할 기준 경로 지정
        "baseUrl": "./",
        // 컴파일러가 참조할 타입 선언(d.ts)의 경로를 지정
        "typeRoots": ["./node_modules/@types"],
    },
    //경로 지정 / 컴파일할 파일 경로 목록
    "include": [
        //지정폴더 안에 있는 모든 ts 파일
        "지정폴더/**/*.ts"
    ],
    //컴파일 시 제외할 파일 목록
    "exclude": [
        "node_modules"
    ]
}

NEST.js를 사용하고싶어서 TypeScript를 한번 배워봤다.
타입을 지정하는 자바스크립트라니 신선하다.
이게 타입스크립트에 끝은 아닐거이기 때문에, NEST를 배워보면서 더 공부하면 좋을 것 같다.

0개의 댓글