[Unit 5] TypeScript(1)

JeongYeon·2023년 5월 30일
0

[SEB FE]section4

목록 보기
12/16
post-thumbnail

TypeScript

TypeScript
마이크로소프트에서 개발한 Js의 상위 집합 언어

TypeScript 등장배경
타입스크립트는 js의 단점을 보완하기위해 등장했다.
js는 동적타입이 결정되어 유연하고 다양한 라이브러리와 프레임워크를 사용할수 있는 장점이 있지만, 타입의 명시성이 부족한 단점이 있다.

let add = (x, y) => {
	return x + y;
}
add(5, "7");

add함수에 숫자 5와 문자열"7"을 전달인자로 전달해 덧셈을 수행하는데 이때 결과는 "57"이 나온다.
이렇게 js는 함수나 변수의 타입을 명시적으로 지정하지 않아도 동작하는 경우가 많아서 예상치 못한 결과를 초래하게 된다.
이런 문제점을 보완하기 위해 TypeScript라는 언어가 등장했다.


TypeScript 장점
TypeScript는 정적타입 검사 기능을 제공해 코드의 가독성과 유지 보수성을 높여준다.
이를 통해 개발자는 런타임 에러 최소화, 코드작성 시간 단축, 협업 시 코드 가독성을 높여준다.

//interface를 사용한 코드의 가독성을 높인 예시
interface User {
  id: number;
  name: string;
}
function greetingUser(user: User) {
	 console.log(`Hello, ${user.name}!`)
}
const parkUser = {
	id: 1,
  name: "박해커"
};
greetingUser(parkUser);

TypeScript타입

타입스크립트는 자바스크립트와 거의 동일한 데이터 타입을 지원한다.
Boolean 타입
boolean값이라고 불리는 참(true), 거짓(false)값

let isShow: boolean = true;
let isDone: boolean = false;

Number 타입
정수와 실수 구분없이 Number타입 하나로 표기

let number1: number = 5;
let number2: number = 0.7;

String 타입
큰따옴표("")나 작은따옴표('')를 사용해 문자열 데이터 표현,
백틱(``)을 사용한 문자열인 템플릿 리터럴을 사용해 문자열 작성 가능

let firstName: string = "coding";
let lastName: string = 'kim';
let longString: string = `Kimcoding is a developer.
He is 20 years old.`

Array 타입
값들을 배열로 다룰수 있고 두가지 방법을 사용할 수 있다.

//첫 번째 방법
let items: string[] = ["apple", "banana", "grape"];
//두 번째 방법
let numberList: Array<number> = [4, 7, 100];

Tuple 타입
요소의 타입과 개수가 고정된 배열을 표현할 수 있다.
배열의 Index마다 타입이 정해져 있어 정확한 index에 접근할 필요가 있다.

let user: [string, number, boolean] = ["kimcoding", 20, true];
console.log(user[2].toString());

Object 타입
원시타입이 아닌 타입을 나타낸다.
TypeScript에서 object타입은 모든 객체를 수용하는 타입으로 객체의 프로퍼티 타입들이 any로 지정되기 때문에 어떤 프로퍼티라도 추가할 수 있지만 추천하는 방법은 아니다.
그래서 객체의 프로퍼티 타입들을 각기 명시해 주는 것이 좋다.

let obj: object = {};
let user: {name: string, age: number} = {
	name: "kimcoding",
	age: 20
}

Any 타입
간혹 알지 못하는 타입을 표현해야 할 때도 있다.
타입 검사를 하고 싶지 않을때 any타입을 사용할 수 있고, any타입을 사용하게 되면 변수에 값을 재할당 하는 겅우 타입을 명시한 변수와 달리 타입에 구애받지 않고 값을 재할당할 수 있다.

let obj: object = {};
//에러가 납니다.
obj = "hello";
let maybe: any = 4;
//정상적으로 동작합니다.
maybe = true;

엄격한 타입검사를 하지 않기 때문에 에러가 나지 않고 실제 할당된 값을 가지지 않는 메서드이기 때문에 반환되는 값은 undefined이다.

let maybe: any = 4;
//undefined로 출력됩니다.
console.log(maybe.length);

any타입은 타입의 일부만 알고, 전체는 알지 못할때도 유용하다.
여러 타입이 섞인 배열을 받고자 할때 유용하다.

let list: any[] = [1, true, "free"];
//any로 다루고 있기 때문에 index 1번째 요소가 boolean 타입이지만 number 타입으로 재할당할 수 있습니다. 
list[1] = 100;

TypeScript 함수

타입스크립트도 자바스크립트처럼 기명함수(named function)와 화살표함수(arrow function)를 만들 수 있다.

//자바스크립트 표현
//named function
function add(x, y){
	return x + y;
}
//arrow function
let add = (x, y) => {
	return x + y;
}
// 타입스크립트 표현
//named function
function add(x: number, y: number):number {
	return x + y;
}
//arrow function
let add = (x: number, y: number): number => {
	return x + y;
}

TypeScript에서 함수를 표현할때 매개변수의 타입과 반환 타입을 명시해야 한다.
만약 함수에 리턴값이 없으면 void를 사용해 작성할 수 있다.

let printAnswer = (): void => {
	console.log("YES");
}

타입스크립트는 js와 달리 매개변수의 개수에 맞춰 전달인자를 전달해야 한다.

let greeting = (firstName: string, lastName: string): string => {
	return `hello, ${firstName} ${lastName}`;
}
//에러가 납니다.
greeting('coding');
//정상적으로 작동합니다.
greeting('coding', 'kim');
//너무 많은 매개변수를 보내 에러가 납니다.
greeting('coding', 'kim', 'hacker');

전달인자를 전달하지 않거나, undefined를 전달했을 때 매개변수의 값을 정해놓을 수도 있다.

let greeting = (firstName: string, lastName="kim"): string => {
	return `hello, ${firstName} ${lastName}`;
}
//정상적으로 작동합니다. 
greeting('coding');
//정상적으로 작동합니다.
greeting('coding', undefined);
//너무 많은 매개변수를 보내 에러가 납니다.
greeting('coding', 'kim', 'hacker');

선택적 매개변수를 원하면 매개변수 이름 끝에 ?를 붙여 해결할 수 있다.`

let greeting = (firstName: string, lastName?: string): string => {
	return `hello, ${firstName} ${lastName}`;
}
//정상적으로 작동합니다.
greeting('coding');
//정상적으로 작동합니다.
greeting('coding', 'kim');
//너무 많은 매개변수를 보내 에러가 납니다.
greeting('coding', 'kim', 'hacker');

TypeScript 연산자 활용 타입

유니온(Union)타입
둘 이상의 타입을 합쳐서 만들어진 새로운 타입으로 |연산자를 이용한다.

function printValue(value: any): void {
  if (typeof value === "number") {
    console.log(`The value is a number: ${value}`);
  } else {
    console.log(`The value is a string: ${value}`);
  }
}
printValue(10); // The value is a number: 10
printValue("hello"); // The value is a string: hello

⬆️ 코드는 value매개변수의 타입을 any로 정의하고, 타입이 number인지 string인지에 따라 if-else문으로 나누어 출력한다.
하지만 이렇게 사용하는 것은 Js와 별 차이가 없기 때문에 유니온 타입을 사용해서 TypeScript의 이점을 살려 코딩하는 것이 좋다.

function printValue(value: number|string): void {
  if (typeof value === "number") {
    console.log(`The value is a number: ${value}`);
  } else {
    console.log(`The value is a string: ${value}`);
  }
}
printValue(10); // The value is a number: 10
printValue("hello"); // The value is a string: hello

유니온 타입의 장점

  • 타입을 추론할 수 있어 API를 쉽게 자동완성으로 얻어낼 수 있다.
    • 하지만 any타입을 사용하면 타입을 추론할수 없어 자동완성 기능을 사용하기 어렵다
      - 코드의 가독성을 높일 수 있다.


      유니온 타입 사용시 유의점
  • 유니온 타입인 값이 있으면, 유니온에 있는 모든 타입에 공통인 멤버들에만 접근할 수 있어 유의해야 한다.
interface Developer {
  name: string;
  skill: string;
}
interface Person {
  name: string;
  age: number;
}
function askSomeone(someone: Developer | Person) {
	console.log(someone.name);
}

인터페이스를 이용해 DeveloperPerson을 정의를 해도
실질적으로는 askSomeone함수 내부에서는 공통으로 가지고있는 name에만 접근할 수 있다.
만약 나머지 프로퍼티에도 접근하고 싶으면 타입가드를 사용해야한다.
💡타입가드 : TypeScript에서 타입을 보호하기 위한 기능 중 하나로 특정 코드 블록에서 타입의 범위를 제한해 해당 코드 블록 안에서 타입 안정성을 보장해 준다.

function askSomeone(someone: Developer | Person) {
  // in 연산자 : 타입스크립트에서 객체의 속성이 존재하는지를 체크하는 연산자
  // in 연산자는 객체의 속성 이름과 함께 사용하여 해당 속성이 객체 내에 존재하는지 여부를 검사
  if ('skill' in someone) {
    console.log(someone.skill);
  }
  if ('age' in someone) {
    console.log(someone.age);
  }
}

TypeScript에서는 in 연산자를 제공하고 있습니다. in 연산자는 객체의 프로퍼티 이름과 함께 사용되며, 해당 프로퍼티가 객체 내에 존재하는지 여부를 검사한다.



인터섹션(Intersection)타입
둘 이상의 타입을 결합해 새로운 타입을 만드는 방법으로 &연산자를 사용해 표현한다.

let value: string & number & boolean;

인터섹션으로 타입을 연결해 하나의 단일 타입으로 표현할 수 있어 타입가드는 필요하지 않다.

interface Developer {
  name: string;
  skill: string;
}
interface Person {
  name: string;
  age: number;
}
function askSomeone(someone: Developer & Person) {
  console.log(someone.age);
	console.log(someone.name);
	console.log(someone.skill);
}

인터섹션 타입은 타입가드는 필요없지만 새로운 합집합을 만들어내는 것이라 전달인자를 전달할 때 모든 프로퍼티를 전부 보내줘야 한다.

interface Developer {
  name: string;
  skill: string;
}
interface Person {
  name: string;
  age: number;
}
function askSomeone(someone: Developer | Person) {
	//이런 식으로 프로퍼티에 접근할 수 있습니다.
  if ('skill' in someone) {
    console.log(someone.skill);
  }
  if ('age' in someone) {
    console.log(someone.age);
  }
}
//유니온 타입은 전달인자를 전달할 때 선택지가 생깁니다.
askSomeone({name: '김코딩', skill: '웹 개발'});
askSomeone({name: '김코딩', age: 20});
function askSomeone2(someone: Developer & Person) {
	//타입 가드를 사용하지 않아도 모든 프로퍼티에 접근할 수 있습니다.
  console.log(someone.age);
	console.log(someone.name);
	console.log(someone.skill);
}
//그러나 인터섹션 타입으로 결합하게 된다면 전달인자를 전달할 때 선택지가 없습니다.
askSomeone2({name: '김코딩', skill: '웹 개발', age:20});

내용 참조, 출처 : 코드스테이츠

profile
프론트엔드 개발자 될거야( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾

0개의 댓글

관련 채용 정보