타입스크립트 1

Minji Lee·2023년 2월 23일
0

typescript

목록 보기
1/2
post-thumbnail

1. 타입스크립트 설정파일 생성(tsconfig.json)

  • 직접 입력하여 생성
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}
  • tsc --init 명령어 입력하여 자동 생성

    만약, typescript가 설치되어 있지 않는 경우 다음 명령어로 설치
    < typescript 설치 명령어(전역적으로 설치) >
    yarn global add typescript

tsconfig.json 파일은 타입스크립트가 컴파일될 때 필요한 옵션 지정해줌

  • target: 컴파일된 코드가 실행되는 환경 정의 → 예를 들어, es5나 es6
  • module: 컴파일된 코드가 사용하는 모듈 시스템 정의 → 'common'으로 설정하면, export default Sampleexports.default=helloWorld로 변환
  • strict: 모든 타입 체킹 옵션 활성화하는지 여부
  • esModuleInterop: commonjs 모듈 형태로 이루어진 파일을 es2015 모듈 형태로 불러올 수 있게 해줌

typescript는 *.ts 확장자 사용

const message: string = "hello world";

: string과 같이 해당 상수 값의 타입 명시 → 다른 타입을 사용할 경우 오류 발생(string으로 명시하였는데, 값을 숫자로 설정하는 경우)


2. 기본 타입

let count = 0; //숫자
count += 1;
count = "갑자기 분위기 문자열"; //에러 발생

const message: string = "hello world"; //문자열

const done: boolean = true; //불리언 값

const numbers: number[] = [1, 2, 3]; //숫자 배열
const messages: string[] = ["hello", "world"]; //문자열 배열

message.push(1); //에러 발생 -> 숫자는 안됨

let mightBeUndefined: string | undefined = undefined; //string/undefined 둘중에 하나
let nullableNumber: number | null = null; // number/null 둘중에 하나

let color: "red" | "orange" | "yellow" = "red"; //red/orange/yellow 셋 중에 하나
color = "yellow";
color = "green"; //3개말고 다른거면 에러
  • 선언할 때 타입을 명시하지 않은 경우, 초기화할 때 입력한 값의 타입이 자동적으로 해당 변수/상수의 타입으로 설정된다.
  • 숫자: number
  • 문자: string
  • true/false: boolean
  • 배열: 타입[]
  • 색 지정할 때 원하는 갯수의 색만 지정하고 싶은 경우에도 사용

3. 함수에서의 타입

function sum(x: number, y: number): number {
  return x + y;
}

sum(1, 2);
  • 맨 뒤의 :number는 해당 함수의 결과값의 타입 명시
  • 타입스크립트 사용하면 함수의 파라미터에 어떤 타입을 넣어야 하는지 알 수 있음
function sumArray(numbers: number[]): number {
  return numbers.reduce((acc, current) => acc + current, 0);
}

const total = sumArray([1, 2, 3, 4, 5]);
  • 타입스크립트는 배열의 내장함수 사용할 때에도 타입의 형태 알 수 있음
  • 함수에서 반환값이 없는 경우, 타입 void로 설정

4. interface 사용

인터페이스(interface): 변수, 함수, 클래스가 만족해야하는 최소규격 지정 해주는 도구
→ 인터페이스를 선언한 변수, 함수, 클래스는 해당 인터페이스를 준수해야함

<클래스에서 인터페이스 사용해보기>

// shape 라는 interface 선언
interface Shape {
  getArea(): number;
  //Shape interface에는 getArea라는 함수가 꼭 존재해야하고 반환값는 숫자이어야함
}

class Circle implements Shape {
  //`implements`키워드 사용하여 해당 클래스가 Shape interface의 조건 충족하겠다고 명시

  radius: number; //멤버 변수 radius 타입 설정

  constructor(radius: number) {
    this.radius = radius;
  }

  // 너비 가져오는 함수 구현
  getArea(): number {
    return this.radius * this.radius * Math.PI;
  }
}

class Rectangle implements Shape {
  width: number;
  height: number;

  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
  }

  getArea(): number {
    return this.width * this.height;
  }
}

const shapes: Shape[] = [new Circle(5), new Rectangle(10, 5)];

shapes.forEach((shape) => {
  console.log(shape.getArea());
});
  • interface 선언한 후, implements 키워드 사용하여 해당 인터페이스 사용
  • 멤버 변수 선언한 후, constructor(생성자)에서 해당 값 다시 하나하나 설정 → 타입스크립트 경우, 멤버 변수 따로 선언하지 않고 constructor의 파라미터에 public 또는 private accessor 사용하여 한번에 설정가능
// shape 라는 interface 선언
interface Shape {
  getArea(): number;
  //Shape interface에는 getArea라는 함수가 꼭 존재해야하고 반환값는 숫자이어야함
}

class Circle implements Shape {
  //`implements`키워드 사용하여 해당 클래스가 Shape interface의 조건 충족하겠다고 명시

  constructor(public radius: number) {
    this.radius = radius;
  }

  // 너비 가져오는 함수 구현
  getArea(): number {
    return this.radius * this.radius * Math.PI;
  }
}

class Rectangle implements Shape {
  constructor(private width: number, private height: number) {
    this.width = width;
    this.height = height;
  }

  getArea(): number {
    return this.width * this.height;
  }
}

const circle = new Circle(5);
const rectangle = new Rectangle(10, 5);

console.log(circle.radius);
console.log(rectangle.width); //불가능

const shapes: Shape[] = [new Circle(5), new Rectangle(10, 5)];

shapes.forEach((shape) => {
  console.log(shape.getArea());
});
  • public으로 선언된 값: 클래스 외부에서도 조회가능
  • private으로 선언된 값: 클래스 내부에서만 조회가능, 외부에서는 불가능

<일반 객체에서 interface 사용>

// 일반객체에서의 인터페이스 사용
interface Person {
  name: string;
  age?: number;
}
interface Developer {
  name: string;
  age?: number;
  skills: string[];
}

const person: Person = {
  name: "김사람",
  age: 20,
};
const expert: Developer = {
  name: "김개발",
  skills: ["javascript", "react"],
};
  • ? 가 들어간 값은 인터페이스 사용 시 설정해도되고 안해도됨을 의미
// 일반객체에서의 인터페이스 사용
interface Person {
  name: string;
  age?: number;
}
interface Developer extends Person {
  skills: string[];
}

const person: Person = {
  name: "김사람",
  age: 20,
};
const expert: Developer = {
  name: "김개발",
  skills: ["javascript", "react"],
};

const people: Person[] = [person, expert];
  • 공통된 값이 많이 존재하는 경우, 다른 인터페이스를 extends키워드 사용하여 상속받아서 사용

5. Type Alias 사용

type: 특정 타입에 별칭을 붙이는 용도로 사용
→ 객체를 위한 타입 설정, 별칭 설정 등

// Type Alias
type Person = {
  name: string;
  age?: number;
};

type Developer = Person & {
  skills: string[];
};

const person: Person = {
  name: "김사랑",
};

const expert: Developer = {
  name: "김개발",
  skills: ["javascript", "react"],
};

type People = Person[];
const people: People = [person, expert];

type Color = "red" | "orange" | "yellow";
const color: Color = "red";
const colors: Color[] = ["red", "orange"];
  • & 는 인터페이스에서 extends와 같은 개념으로, 두 개 이상의 타입을 합쳐줌(intersection)
  • interface 대신 type을 쓰면됨
  • 'type People = Person[];'는 Person[]을 People 이라는 타입으로 사용할 수 있다는 의미

❗️ type과 interface의 용도
일관성있게 아무거나 사용해도 상관은 없지만, 클래스 관련 타입은 interface사용하는게 좋고, 일반 객체 타입은 type을 사용해도 무방하다.


6. Generics

함수, 클래스, 인터페이스, 타입 별칭을 사용하게 될 때 여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법

제네릭(Generic)
데이터 형식에 의존하지 않으면서, 다른 데이터 타입들로 사용할 수 있는 방법
즉, 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징으로, 한가지 타입보다 여러가지 타입에서 동작하는 컴포넌트를 생성하는데 사용

[사용방법]

// generics 사용 전
function getText(text: any): any {
  return text;
}

getText("hi"); //hi
getText(10); //10
getText(true); //true

위와 같이 어떤 값을 넣을지 또는 어떤 값을 반환할지 모르는 경우(any사용한 경우) 제네릭을 사용하면 됨

// generics 사용
function getText<T>(text: T): T {
  return text;
}

getText<string>("hi"); //hi
getText<number>(10); //10
getText<boolean>(true); //true
  • T(type)을 사용하여 값 설정 시 타입 지정할 수 있게끔
  • 값 설정할 때 T 자리에 해당 타입을 넣어주면됨

1) 인터페이스에서 제네릭 사용

interface Itmes<T> {
  list: T[];
}

const items: Itmes<string> = {
  list: ["a", "b", "c"],
};

2) type에서 제네릭 사용

type Itmes<T> = {
  list: T[];
};

const items: Itmes<string> = {
  list: ["a", "b", "c"],
};

3) 클래스에서 제네릭 사용

class GenericMath<T>{
	pi: T;
    sum: (x:T, y: T) => T;
}
let math = new GenericMath<number>();

0개의 댓글