TS | 타입스크립트 사용 이유, 기본 타입, 인터페이스, 함수

지현·2023년 7월 21일
0

Javascript / TypeScript

목록 보기
15/16
post-thumbnail

요즘 대세를 따르기 위해 타입스크립트 기초 강좌를 보며 정리해보려한다. 그동안 JavaScript만 써왔어서 걱정되지만 변화하는 흐름을 따라가기 위해.... 영상은 코딩앙마 유튜브 영상을 시청했다.

타입스크립트를 사용하는 이유

  • 우리가 사용하는 브라우저는 타입스크립트를 이해하지 못한다. 즉, 브라우저가 타입스크립트를 이해하기 위해서는 자바스크립트 언어로 변환한 뒤 읽을 수 있다. 그럼에도 불구하고 타입스크립트를 사용하는 이유는 무엇일까 알아보자.

예시

자바스크립트에서 실행

function add(num1,num2){
  console.log(num1+num2);
}
add(); // NaN
add(1) // NaN
add(1,2) // 3
add(3,4,5) // 7 
add('hello','world');//'helloworld'

숫자 두개를 받아서 둘을 더하는 함수를 만든다고 가정해보자. 인간은 글자만 봐도 인수가 number 여야 한다는 것을 알지만 컴퓨터는 그것을 모른다. 그러나 add함수에 인자 없이 함수를 실행할 때 자바스크립트에서 실행할 경우 아무런 오류 없이 NaN 이 반환된다. (undefined+undefined = NaN), 그 외 인수의 개수를 맞추지 않거나 의도한 바가 아닌 문자열을 입력해도 자바스크립트는 아무런 경고 없이 문자열도 더해준다ㅠ

예시2

자바스크립트에서 실행

function showItems(arr){
  arr.forEach((item)=>{
    console.log(item);
  });
}

showItems([1,2,3]) ; // 1 2 3
showItems(1,2,3) // TypeError (배열이 아니라 에러 뜸)

배열의 요소를 반환하는 showItems 함수에 배열이 아닌 값을 넣게 되면 타입 에러가 뜬다.

JavaScript는 동적언어, 런타입에 타입이 결정되고 오류를 발견한다. 개발자가 실수할 때 사용자는 고스란히 오류를 발견하게 된다.
반면 Java 나 TypeScript의 경우는 정적언어, 컴파일할 때 타입이 결정되고 오류를 발견한다.

예제를 타입스크립트로 실행해보자

function add(num1:number,num2:number){
  console.log(num1+num2);
}
add(); // error : Expected 2 arguments, but got 0
add(1) // error : Expected 2 arguments, but got 1
add(1,2) // 3  (^^)
add(3,4,5) // error : Expected 2 arguments, but got 3
add('hello','world');// error : Argument of type 'string' is not assignable to parameter of type 'number'
function showItems(arr:number[]){
  arr.forEach((item)=>{
    console.log(item);
  });
}

showItems([1,2,3]) ; // 1 2 3
showItems(1,2,3) // error : Expected 1 arguments, but got 3

이처럼 타입스크립트는 개발하면서 발생할 수 있는 타입 에러들을 미리 감지하여 알려준다!

기본 타입

//string
let car: string = 'bmw';
// car = 3 ; // type error

//number
let age: number = 30;

//boolean
let isAdult: boolean = true;

//array (number)
let a: number[] = [1, 2, 3];
let a2: Array<number> = [1, 2, 3];

//array(string)
let week1: string[] = ['mon', 'tue', 'wed'];
let week2: Array<string> = ['mon', 'tue', 'wed'];

// 튜플(Tuple) - 인덱스별로 타입 다를 때 사용 가능
let b: [string, number] = ['hello', 123];
b[0].toLowerCase(); // 가능
// b[1].toLowerCase() // error : 'toLowerCase' does no exist on ype 'number'

//void - 아무것도 반환하지 않을 때
function sayHello(): void {
  console.log('hello');
}

//never - 항상 에러 반환하거나 영원히 끝나지 않는 타입
function isfLoop() {
  while (true) {
    //do something..
  }
}

//enum - 비슷한 값들끼리 묶어줌 , 알아서 1씩 증가시켜서 값 배정
enum Os {
  Window, //1
  Ios, //2
  Android, //3
}
let myOs: Os; // Os에 있는 것만 입력할 수 있음

// null , undefined
let nulla: null = null;
let nullb: undefined = undefined;

인터페이스 (Interface)

인터페이스는 상호 간에 정의한 약속 혹은 규칙을 의미한다. (속성과 속성의 타입, 파라미터, 접근 방식, 클래스 등)

인터페이스 예제

user라는 object 를 만든다고 가정해보자.

let user:object;

user = {
  name : 'xx',
  age : 30
}

console.log(user.name) // error : Property 'name' does not exist on type 'object'

프로퍼티 정의해서 객체로 표현하고자 할 때는 인터페이스를 사용한다.

type Score = 'A' | 'B' | 'C' | 'F';

interface User {
  name: string;
  age: number;
  gender?: string; // optional 한 항목 만드려면 항목 이름 뒤에 ? 붙이고 타입 설정해준다.
  readonly birthYear: number; // 값 수정 못하게 하려면 항목 이름 앞에 readonly 라고 써준다.
  [grade: number]: Score; // 문자열 인덱스 서명 추가하기 [key : type] : type (이 경우는 직접 Scroe 타입 만들어서 Score타입 넣어줌)
}

let user: User = {
  name: 'xx',
  age: 30,
  birthYear: 2000,
  1: 'A',
  2: 'B',
};

user.gender = 'male';
// user.birthYear = 1900;//error:Cannot assign to 'birtyYear' because it is a read-only property

console.log(user.age); // 30
interface Add {
  (num1:number,num2:number) : number;
}

const add : Add = function (x,y){
  return x + y;
}

add(10,20) // 30

boolean 값 반환하는 interface

interface IsAult {
  (age:number):boolean;
}

const a:IsAdult = (age) =>{
  return age > 19;
}

a(33) // true

interface로 class 만들기 (implements)

//implements

interface Car {
  color : string;
  wheels : number;
  start() :void;
}

class Bmw implements Car{
  color;
  wheels = 4;
  
  constructor(c:string){
    this.color = c'
  }
  start(){
    console.log('go..');
  }
  const b =  new Bmw('green')
    consoe.log(b) // 'wheels' : 4, 'color' : 'green'
	b.start(); // 'go...'

interface는 확장 (extends)

interface Benz extends Car{
  door : number;
  stop() : void;
}

const benz : Benz = {
  door : 5,
  stop(){
    console.log('stop')
  }
  color : 'black',
  wheels : 4,
  start
}

interface는 여러개 이용해서 확장 가능

interface Car {
  color : string;
  wheels : number;
  start():void;
}
interface Toy {
  name : string;
}

interface ToyCar extends Car, Toy {
  price : number;
}

함수

function add(num1:number,num2:number):number{
  return num1+num2;
}

//반환값 없는 경우에는 함수의 반환값 타입을 void로 지정
function add(num1:number,num2:number):void{
  console.log(num1+num2)
}

함수 매개변수 선택적으로 지정

function hello(name?:string){ // name 뒤에 ? 붙여서 optional로 지정 (입력 해도 되고 안해도 됨)
  return `Hello, ${name||"world"}`;
}

function hello2(name = 'world'){
	return `Hello, ${name}`;
}
const result = hello()
const result2 = hello('sam')
const result3 - hello(123) // error
function hello(name:string, age?:number):string{ // 선택적 매개변수는 무조건 필수 매개변수 뒤에!
  if(age !== undefined){
    return `Hello, ${name}. You are ${age}.`'
  }else {
    return `Hello, ${name}`;
  }
}
console.log(hello('Sam')); // Hello, Sam
console.log(hello('Sam',30));//Hello, Sam. You are 30

rest parameter(...par :전달받은 매개변수 배열로)

function add(...nums: number[]){
  return nums.reduce((result,num)=> result + num,0);
}

add(1,2,3) // 6
add(1,2,3,4,5,6,7,8,9,10) //55

this의 타입지정

this의 타입은 맨 앞에 써준다.

interface User{
  name:string;
}

const Sam : User = {name : 'Sam'}

function showName(this:User , age:number,gender:'m'|'f'){
  console.log(this.name,age,gender)
}

const a = showName.bind(sam);
a(30,'m'); // "Sam , 30, 'm'"

함수 오버로드

함수 오버로드는 전달받은 매개변수의 개수나 타입에 따라 다른 동작을 하게하는 것을 말한다.

interface User3 {
  name: string;
  age: number;
}

//함수 오버로드
function join(name: string, age: string): string; // age가 string이면 string 반환
function join(name: string, age: number): User3; // age가 number면 User반환

function join(name: string, age: number | string): User3 | string {
  if (typeof age === 'number') {
    return {
      name,
      age,
    };
  } else {
    return '나이는 숫자로 입력하셈';
  }
}

const sam: User3 = join('Sam', 30); // 'Sam',30'
const jane: string = join('Jane', '30'); // '나이는 숫자로 입력하셈'

0개의 댓글