[Typescript] 타입스크립트 타입(1)

soob·2022년 6월 30일

typescript

목록 보기
1/2
post-thumbnail

Typescript 쓰는 이유

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"

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

showItems([1, 2, 3]);
showItems(1, 2, 3); // Uncaught TypeError

add(1, 2)를 제외하고 원하는 사용 방식이 아니다.
Javascript는 동적언어로 런타임에 타입결정되고 그 때 오류가 발견된다.
개발자가 실수하면 사용자가 오류를 볼 수 있다.
Java, TypeScript(정적언어)은 컴파일 타임에 타입이 결정된다.
코드 작성 시간이 길지만 안정적이고 빠르게 작업을 진행할 수 있다.

function add(num1: number, num2: number) {
	console.log(num1 + num2);
}

add(); // error
add(1); // error
add(1, 2); // 3
add(3, 4, 5); //  error
add("hello", "world"); // error

function showItems(arr: number[]) {
	arr.forEach((item) => {
    	console.log(item);
    })
}

showItems([1, 2, 3]);
showItems(1, 2, 3); // error

무분별한 any 사용은 하지 않는 것이 좋다.

typescript 기본타입

let car:string = "bmw";
let age:number = 30;
let isAdult:boolean = true;
let a:number[] = [1,2,3];
let a2:Array<number> = [1,2,3];

let week1:string[] = ["mon", "tue", "wed"];
let week3:Array<string> = ["mon", "tue", "wed"];

week1.push(3); // error

튜플(Tuple)

let b:[string, number];

b= ["z", 1];
//b = [1, "z"]; error
b[0].toLowerCase();
b[1].toLowerCase(); // Property 'toLowerCase' does not exist on type 'number'

요소의 수가 고정되었고 특정 순서 또는 특정 패턴으로 이루어진 데이터를 표현하는 경우 사용한다. 배열의 첫 번째는 string, 두 번째는 number가 들어가야한다.

void, never

void
함수에서 아무것도 반환하지 않을 때 사용한다.

function sayHello():void {
	console.log("hello");
}

never
항상 에러를 반환하거나 영원히 끝나지 않는 함수일 때 사용한다.

function showError():never {
	throw new Error();
}

function infLoop():never {
	while(true) {
    	//
    }
}

enum

특정 값을 사용하지만 그 값들이 공통점이 있을 경우 사용한다.

enum Os {
	Window = 3, // 3
  	Ios = 10, // 10
  	Android // 11
}

console.log(Os['Ios']);

enum Os2 {
	Window = "win", 
  	Ios = "ios" , 
  	Android = "and" 
}

let myOs:Os2;
myOs = Os2.window;

기본으로는 0,1,2 값이 들어간다. 문자열도 들어갈 수 있다.

null, undefiend

let a:null = null;
let b:undefined = undefined;

Interface - 객체, 함수, 클래스

let user:object;

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

console.log(user.name); //error

특정 속성값에 대한 타입을 정의해줘야한다.
프로퍼티를 정의해서 사용할 때는 인터페이스를 사용해야 한다.
?를 써줘서 정의하면 있어도 없어도 되는 값이다.


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

interface User {
	name: string,
    age: number,
  	gender? : string, // ? - 선택적 매개변수
    readonly birthYear: number,
    [grade:number] : Score; //grade는 네이밍은 상관없음. Score에 들어간 값만 가능하다. 다른 값 넣으면 에러발생
}

let user: User = {
	name: 'xx',
  	age: 25,
  	birthYear: 1990,
  	1: "A",
    2: "B"
}

console.log(user.age);
user.age = 10;
user.gender = "male";
//user.birthYear = 1990; error

함수

interface Add {
	(num1:number, num2:number): number;
}

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

add(10, 20);

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

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

a(33);

클래스

implements를 사용한다.
새로운 클래스의 모양을 동일하게 정의하고 싶을 때 사용한다.

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

class Bmw implements Car {
	//color = "black";
    wheels = 4;
  	constructor(c:string) {
    	this.color = c;
    }
    start() {
    	console.log('go...');
    }
}

const b = new Bmw('black');

extends 확장

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

const benz: Benz = {
	door: 5,
  	stop() {
    	console.log('stop');
    },
  	color: 'black',
  	wheels: 4,
  	start() {}
}
//모두 입력해줘야한다.

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

interface Toy {
	name: string;
}

interface ToyCar extends Car2, Toy {
	price: number
}

선택적 매개변수

function hello(name?: string) {
	return `Hello, ${name || "world"}`;
}

//js에서 기본값 넣기
function hello2(name = "world") {
	return `Hello, ${name}`;
}

const result = hello(); 
const result2 = hello('Sam');

/*
옵셔널하게 사용하는 값은 뒤에 넣어준다.
옵션값을 앞 매개변수에 넣어 줄 경우엔 아래와 같이 써준다.
age: number | undefined, name: string
hello3(undefined, "Sam"); 앞에 undefined 전달
*/
function hello3(name: string, age ?: number): string {
	if(age !== undefined) {
    	return `Hello, ${name}. You are ${age}.`;
    } else {
    	return `Hello, ${name}`;
    }
}

console.log(hello3("Sam"));
console.log(hello3("Sam", 30));

나머지 매개변수

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

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'); //this 다음 매개변수부터 차례대로 적용된다. 3개가 있다고 헷갈리지 말자.

bind()
새롭게 바인딩한 함수를 만드는 함수로, 바인딩한 함수는 원본 함수 객체를 감싸는 함수로써, 바인딩한 함수를 호출하면 일반적으로 래핑된 함수가 호출 된다.

overloading

같은 이름을 가진 함수를 여러 개 정의할 수 있으며 각 함수는 서로 다른 타입을 가지는 매개변수로 정의해야 합니다. 매개변수가 다르며 이름이 동일한 함수.

interface User {
	name: string,
    age: number
}

function join(name: string, age: number): User;
function join(name: string, age: string): string;
function join(name: string, age: number | string): User | string {
	if(typeof age === "number") {
    	return {
        	name,
            age
        }
    } else {
    	return "나이는 숫자로 입력해주세요."
    }
}

const sam: User = join("Sam", 30);
const jane: string = join("Jane", "30");

0개의 댓글