Typescript 기초개념 정리

2023. 2. 14. 22:23·TECH

Typescript로 블록체인 만들기 강의를 토대로 정리한 내용입니다. 

 

Typescript

타입스크립트는 자바스크립트기반으로 만들어진 언어
자바스크립의 여러문제를 해결하고 보완하기 위해 만들어진 언어

strongly-typed언어 - 프로그래밍 언어가 작동하기 전에 type을 확인한다.

 

Typescript 사용하면 좋은점

- 코드에 버그가 줄어든다.

- 더 나은 개발자경험을 제공한다.

 

타입의 종류

let a:number 
let b:string
let c:boolean

// array type
let a:number[]
let a:string[]
let a:boolean[]

//object type
const player : {
  name: string,
  age: number
} = {
  name: 'aa',
  age: 17
}

// object type (property이름은 모르지만 타입만 알고있는 경우)
// 많이 사용된다. 
type Words = {
  [key: string]: string //key에는 아무 문자열이 와도 된다.
};
let dict: Words = {
  "potato": 'food'
}

//optional type
const player : {
  name: string,
  age?: number //있을수도 있고 없을수도 있는 optional 값
} = {
  name: 'aa',
}

 

type alias 설정

타입을 여러군데에서 공통으로 사용한다면 type alias를 사용하는 것을 권장한다.

타입을 재사용할 수 있게 해준다. 

type alias 의 첫번째 문자는 대문자로 써주기!

type Player = {
  name: string,
  age?: number
}

const player : Player = {
  name: 'aa'
}

const player2 : Player = {
  name: 'bb'
  age: 18
}

 

return 하는 값 타입 정해주기

type Player = {
  name: string,
  age?: number
}

// return하는값 타입으로 함수 뒤에 :하고 타입을 명시해 준다.
function playerMaker(name: string) : Player {
  return {
    name
  }
}

const nico = playerMaker("nico");
nico.age = 12;

 

readonly 속성을 추가할 수있다.

type Player = {
  readonly name: string,
  age?: number
}

// return하는값 타입으로 함수 뒤에 :하고 타입을 명시해 준다.
function playerMaker(name: string) : Player {
  return {
    name
  }
}

const nico = playerMaker("nico");
nico.age = 12;
nico.name = 'aa'; //error

 

Tuple

array를 생성할 수있게 한다.
최소한의 길이를 가져야하고 특정위치에 특정타입이 있어야한다. 

const player: [string, number, boolean] = ["nico", 1, true];

//readonly
const player: readonly [string, number, boolean] = ["nico", 1, true];

 

any 

아무타입이나 허용한다. 

사용하지 않는 것을 추천. any를 사용하면 자바스크립트 코드로 사용하는 것과 같다.

 

unknown

어떤 타입이 오는지 모르는 변수를 사용할 때

해당 변수로 어떤 작업을 하려면 이변수의 타입을 먼저 확인해야한다. 

let a:unknown;

if (typeof a === 'number'){
  let b = a + 1;
}

if(typeof a === 'string'){
 let b = a.toUpperCase();
}

 

void

아무것도 return하지 않는 함수를 대상으로 한다. 

보통 void는 따로 지정해 줄 필요는 없다.

function hello() {
  console.log('hello');
}

 

never

절대 실행되지 않아야한다. 

function Hello(name: string | number) {
  if(typeof name === string) {
    name //string
  } else if(typeof name === number) {
    name //number
  } else {
    name //never
  }
}

 

event객체

타입스크립트에서는 e.target(이벤트가 일어난 target) 대신 e.currentTarget(이벤트가 bind된 target)을 사용한다. 
이유는 요 블로그에 잘 정리되어있다. https://nuhends.tistory.com/115

 

이벤트 객체에 타입을 명시해 줄 때 아래 코드처럼 작성해 주면된다. 
해당 이벤트 어떤 이벤트인지 확인하고 싶을 때
react syntheticEvent 참고

// <>안에 들어가는 값은 어디에서 이벤트가 발생했냐 
event: React.FormEvent<HTMLInputElement>
event: React.MouseEvent<HTMLButtonElement>

 

call signatures 

함수위에 마우스를 올렸을 때 가이드 문구로 보게 되는 것

인자타입이랑 함수의 반환타입을 알려준다.

// 방법1
type Add = (a: number, b: number) => number;
// 방법2 
type Add = {(a: number, b: number) : number};

const add:Add = (a, b) => a + b;

 

오버로딩(overloading)

오버로딩은 여러 call signatures가 있는 함수

type Add = {
	(a: number, b: number) : number
	(a: number, b: string) : number
}

const add: Add = (a, b) => {
	if(typeof b === 'string') return a;
  	return a + b;
}

 

받는 파라미터 개수가 다른 경우

공통으로 받는 파라미터가 아닌경우는 옵셔널 처리를 해줘야한다. 

type Add = {
	(a: number, b: number) : number,
	(a: number, b: number, c: number) : number,
}

// c 옵셔널 처리를 해줘야한다.
const add:Add = (a, b, c?:number) => {
	if(c) return a + b + c;
	return a + b
}

 

다형성

다형성이란 ? 다른모양의 코드를 가질수있게 해주는 것
다형성을 이룰 수 있는 방법? 제네릭 사용

 

제네릭 (generic)

타입의 placeholder
타입이 뭔지 추론해서 타입기준으로 바꿔준다.
call signature를 작성할 때 확실한 타입을 모르는 경우 사용한다. 
<> 안에 원하는 placeholder명을 넣어주면 된다.

type SuperPrint = {
	<TypePlaceholder>(arr: TypePlaceholder[]) : TypePlaceholder 
}

// generic이 두개 오는 경우
type SuperPrint = <T, M>(a: T[], b: M) => T;
type SuperPrint = {
    <T>(arr: T[]):T
};

const superPrint:SuperPrint = (arr) => {
    return arr[0]
}

superPrint([1, 2, 3]);
superPrint(['1', '2', '3']);
superPrint(['1', '2', 3, true]);
type Player<E> = {
	name: string,
  extraInfo: E
}
type NickPlayer = Player<{favFood: string}>

const nick:NickPlayer = {
  name: 'nico',
  extraInfo: {favFood: 'kimchi'}
}

 

제네릭 사용해서 타입선언

type A = Array<number> //number[] 이렇게 사용할 수도 있다.
let a:A = [1, 2, 3, 4];

 

classes

private, public, protected

자바스크립트에는 없는 개념
타입스크립트에서 검증을 하고 자바스크립트로 컴파일되기 때문에 안전하게 사용할 수있다.

class Test {
    constructor(
        private firstname: string,
        private lastname: string,
        public nickname: string
    ) {}
}

const test = new Test('nico', 'last', 'slRh');
test.nickname = 'ggg';
test.firstname = '하'; // Test 클래스 안에서만 수정가능한 private이므로 error

Private: 인스턴스 밖에서 접근할 수없고, 자식클래스에서도 접근할 수 없다.
다른자식 클래스에서 사용하고 싶다면 private를 사용하지 않는다.
Protected: 클래스 밖에서는 접근안됨, 자식클래스에서는 사용할수있다.
Public : private, protected 를 사용하지 않으면 public 이다.

property뿐만 아니라 method에서도 작동한다.

class Test {
    constructor(
        private firstname: string,
        private lastname: string,
        public nickname: string
    ) {}
  
  	private getFullName () {
      return `${this.firstname} ${this.lastname}`;
    }
}

const test = new Test('nico', 'last', 'slRh');
test.getFullName() //private속성이라 error

 

Abstract (추상클래스)

추상클래스는 오직 다른곳에서 상속받을수만 있는 클래스

자바스크립트에는 추상클래스 개념이 없다.

 

추상클래스를 사용하는이유 ? 

표준화된 property와 메소드를 갖도록 해주는 청사진을 만들기위해 추상클래스를 사용한다.

abstract class User {
    constructor(
          private firstname: string,
          private lastname: string,
          public nickname: string
    ) {}
}

class Player extends User {  
} // O

const test = new User('nico', 'last', 'slRh'); // error

 

추상메소드

추상메소드를 만들려면 메소드를 클래스안에서 구현하지 않으면 된다.
메소드의 call signature만 작성해야한다.
상속받는 곳에서 구현을 해야하는 메소드를 의미한다.

abstract class User {
    constructor(
          private firstname: string,
          private lastname: string,
          public nickname: string
    ) {}
  	abstract getNickname():void
}

class Player extends User {  
	getNickname() { //상속받는 클래스에서 구현을 해줘야한다.
    return this.nickname; 
  }
}

const test = new Player('nico', 'last', 'slRh');

 

class객체를 타입으로 선언할 수 있다.

아래 코드에서 Word클래스를 타입으로 선언한걸 확인할 수있다.

type Words = {
    [key: string] : string;
}

class Dict {
    private words: Words;
    constructor() {
        this.words = {}
    }
    add(word: Word) {
        if (this.words[word.term] === undefined) {
            this.words[word.term] = word.def;
        }
    }
    def(term: string) {
        return this.words[term];
    }
}

class Word {
    constructor(
        public term: string,
        public def: string
    ) {}
}

const kimchi = new Word('kimchi', '한국의 음식');
const dict = new Dict();

dict.add(kimchi);
dict.def('kimchi');

 

Word 클래스의 property는 public사용하고 싶지만 수정이 안되게 할수있다. 
readonly를 사용해서 읽기전용으로 만들어준다.

class Word {
    constructor(
        public readonly term: string,
        public readonly def: string
    ) {}
}

 

type으로 특정 값 지정 할 수 있다.

type Team = 'red' | 'blue' | 'yellow';

type Player = {
  name: string,
  team: Team
}

const test: Player = {
    name: 'ddd',
    team: 'yellow' //Pink입력하면 error
}

 

interface 인터페이스

interface는 오로지 오브젝트의 모양을 타입스크립트에게 설명해 주기 위해서만 사용한다.
type은 다양한 용도로 더 많이 사용된다.

object type을 선언할때는 interface를 많이 사용한다. 이유는 밑에서 설명한다!

type Team = 'red' | 'blue' | 'yellow';

interface Player {
  name: string,
  team: Team
}

const test: Player = {
    name: 'ddd',
    team: 'yellow'
}

styled-components로 선언한 css컴포넌트에 interface 적용하기

interface ContainerProps {
  bgColor: string;
}
const Container = styled.div<ContainerProps>`
  background-color: ${(props) => props.bgColor}
`

 

타입상속

interface는 클래스 처럼 extends해서 상속한다.

interface User {
	name: string
}
interface Player extends User {}

const nico: Player = {
  name: 'nico'
}

 

type으로 사용할 때 상속

type User = {
	name: string
}
type Player = User & {}

const nico: Player = {
  name: 'nico'
}

 

property 축적

interface 3번 각각 만들면 타입스크립트가 하나로 합쳐준다. type은 지원하지 않는다.

interface User {
  name: string
}
interface User {
  lastName: string
}
interface User {
  health: number
}

const nico:User = {
  name: 'nico',
  lastName: 'last',
  health: 10
}

 

class 대신 interface를 써야하는 이유

1. 클래스는 아니지만 클래스의 모양을 특정할 수있게 해주는 간단한 방법

2. 자바스크립트로 컴파일 되면 없어지는 코드라 코드를 가볍게 만들어준다. 

3. 추상클래스처럼 강제성도 줄 수있다. 선언된 property가 없으면 오류가 난다.

interface User {
    firstName: string,
    lastName: string,
    sayHi(name: string): string,
    fullName(): string
}

// class extends 대신 implements를 사용한다.
// type도 implements로 사용할 수 있다.
class Player implements User {
  	// 인터페이스를 상속할때는 private, protected 속성을 사용할수없다.
		// pulic만 가능하다.
    constructor(
        public firstName: string,
        public lastName: string,
    ) {}

    sayHi(name: string){
        return 'hi'
    }

    fullName() {
        return `${this.firstName} ${this.lastName}`
    }
}

 

여러가지 인터페이스를 상속하는 경우

interface User {
    firstName: string,
    lastName: string,
    sayHi(name: string): string,
    fullName(): string
}
interface Human {
  healty: number
}
// interface 여러개 상속하는경우 
class Player implements User, Human {
    constructor(
        public firstName: string,
        public lastName: string,
        public healty: number
    ) {}

    sayHi(name: string){
        return 'hi'
    }

    fullName() {
        return `${this.firstName} ${this.lastName}`
    }
}

 

 

useState 타입선언

기본적으로 처음에 default value값으로 들어간 데이터 타입을  확인하고 타입스크립트가 추론하지만 
예외적으로 하나의 state에 문자열, 숫자가 동시에 들어가는경우는 타입을 선언해 줘야한다.

const [value, setValue] = useState<number | string>(0);
setValue(2);
setValue('안녕');
setValue(true); //error

 

enum (enumerable)

실수를 방지하기 위해 사용하는 상수같은 개념

값 할당없이 사용하는 enum에는 자동으로 0, 1, 2 값이 들어간다. 
값을 지정하고 싶은경우 값 할당을 해주면 된다. 

export enum Categories {
  "TO_DO", //0 실제값
  "DOING", //1
  "DONE"   //2
}

export enum Categories {
  "TO_DO" = "TO_DO", //TO_DO
  "DOING" = "DOING", //DOING
  "DONE" = "DONE"  //DONE
}

export const selectState = atom<Categories>({
  key: 'select',
  default: Categories.TO_DO
})

 

'TECH' 카테고리의 다른 글

redux개념 정리  (0) 2023.02.16
tsconfig.json 기본세팅, d.ts, JSDoc  (0) 2023.02.14
async, await 알아보기  (0) 2022.03.30
프론트개발시 CORS 오류와 해결방법!  (0) 2022.03.20
Promise에 대해 알아보자!  (0) 2021.09.26
'TECH' 카테고리의 다른 글
  • redux개념 정리
  • tsconfig.json 기본세팅, d.ts, JSDoc
  • async, await 알아보기
  • 프론트개발시 CORS 오류와 해결방법!
ssund
ssund
  • ssund
    ssund의 기술블로그
    ssund
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • TECH (22)
      • NOTE (40)
      • DAILY (7)
      • javascript (1)
      • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • TECH
    • NOTE
    • DAILY
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    slidesPerGroup
    함수와 메서드차이
    call signatures
    styled-components
    git배포
    웹브라우저구성
    React
    d.ts
    reat-head
    커머스프로젝트
    theme-provider
    TypeScript
    JavaScript
    redux
    reduxtoolkit
    타입스크립트
    react state management
    global-style
    Array.sort()
    배열요소순서
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
ssund
Typescript 기초개념 정리
상단으로

티스토리툴바