#1 TS를 왜 쓸까?
- 자바스크립트 : 동적 언어. 런타임 시간에 타입을 결정, 오류 발견
- 타입스크립트 : 정적 언어. 컴파일 타임에 타입 결정, 오류 발견
즉, 컴파일 과정에서 오류를 발견함으로 효율을 더 높여주고, 코드를 공유할 시에 가독성이 높아진다.
아래의 경우, 인자의 타입(number인지, number로 이루어진 배열인지)를 명확히 표시해줌으로써 에러 방지를 할 수 있다.
function add(num1:number, num2:number){
console.log(num1+num2);
}
function showItems(arr:number[]){
arr.forEach((item)=>{
console.log(item);
})
}
add(2,3);
showItems(1,2,3)
#2 기본 타입 (number, string, 배열, void, never, enum, null ...)
그렇담 어떻게 사용하나?
let car = '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 week2:Array<string>=['mon','tue','wed'];
크게 number, boolean, string, Array<>, type[] 이런식으로 쓰인다.
해당 변수 옆 : 타입명 이런 꼴
//1. 튜플 (tuple)
let b:[string,number];
b=['z',1]; //b=[1,'z']는 불가
b[0].toLowerCase();
타입이 섞인 튜플은 위처럼 괄호 안에 타입명을 명시한다.
하지만 순서대로 타입명을 잘 지켜 써야한다.
//2. void, never
function sayHello():void{ //아무것도 반환하지 않는 경우
console.log('hello');
}
function showError():never{ //에러를 반환하거나
throw new Error();
}
function infLoop():never{ //무한 루프를 도는 경우
while(true){
//do something...
}
}
함수는 반환값이 명확하지 않는 경우도 존재한다. 이런 경우엔 어떻게 적어줄까?
!
아무것도 반환하지 않는 경우엔 void를,
에러 혹은 무한 루프를 반환하는 경우엔 never를 쓴다.
//3. enum : 비슷한 것들끼리 묶여있는, 특정 값으로 매핑됨
enum Os{
Window,
Ios,
Android,
}
let myOs:Os;
myOs=Os.Window;
enum이라는 타입을 정의하여
비슷한 것들 중에서 타입을 선택하여 쓸 수 있도록 할 수 있다.
//4. null, undefined
let p:null=null;
let q:undefined=undefined;
타입이 딱히 정해지지 않거나 null 값일 경우엔 위와 같이 표시해준다.
#3 인터페이스 (interface)
인터페이스란, 하나의 클래스 같은 것이다.
객체를 정의할 때 참조하는 하나의 타입 클래스가 모인 클래스 = 인터페이스
//1
type Score='A'|'B'|'C'|'F';
interface User {
name:string;
age:number;
gender?:string; //? -> 있어도 되고 없어도 되고
readonly birthYear:number; //readonly -> 읽기 전용, 처음 값 할당만 됨
[grade:number]:Score; //number를 key로, Score(또 하나의 type)를 value로 받음
}
let user:User={
name:'xx',
age:30,
birthYear:2000,
1:'A',
2:'B'
}
user.age=10;
user.gender="male";
//user.birthYear=1990; -> 재할당 오류
console.log(user.name)
user라는 객체는 User라는 인터페이스를 참고하여 타입을 설정한다 !
위 코드의 경우에는 grade라는 key에서 Score라는 타입을 참조하는 경우도 있다.
참고로 인터페이스에서 정의한 타입이 굳이 없어도 될 경우엔 변수옆에 ?를 쓰고,
타입의 초기화만 변수 할당에 있어 허용할 때는 readonly를 쓴다.
//2
//interface로 함수 만들기
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; //19보다 크면 참 반환
}
인터페이스로 함수의 입출력 형을 정의해줄 수도 있다.
//3
//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'); //생성될 때 color값 입력
console.log(b);
b.start();
인터페이스를 implements하여 활용할 수도 있다.
위 코드에서는 constructor를 이용해 생성할 때 인자값을 color로 지정하는 기능을 한다.
interface, class, implements, constructor, new, 객체 등의 개념이 집합된 중요한 코드.
//4
interface Benz extends Car{ //Car에 추가적인 타입 넣어서 확장
door:number;
stop():void;
}
//여러 개도 확장 가능
interface Car{
color:string;
wheels:number;
start():void;
}
interface Toy{
name:string;
}
interface ToyCar extends Car, Toy{
price:number;
}
기존 인터페이스에서 extends하여 새로운 인터페이스를 만들 수 있다.
#4 함수
인터페이스로 함수 입출력 형을 결정해주기 이전에, 곧바로 함수에다가 타입을 지정하는 방법도 있다.
//1
function add(num1:number, num2:number):number{
return num1+num2;
}
function isAdult(Age:number):boolean{
return Age>19;
}
function hello(name?:string){ //? -> 선택적 매개변수 있어도되고 없어도되고
return `hello, ${name||"world"}`; //${name}이 없으면 'world'로 대체
}
function hello2(name="world"){
return `hello, ${name}`;
}
const result=hello();
선택적 매개변수를 넣어주고, 대체값을 설정해주는 예시
${변수명||"대체값"}
//2
function hello(age: number | undefined, name: string): string { //age는 ? 대신 선택적 매개변수
if (age !== undefined) {
return `Hello, ${name}. You are ${age}.`;
} else {
return `Hello, ${name}`;
}
}
console.log(hello(30, "Sam"));
console.log(hello(undefined, "Sam"));
받아야 하는 인자값이 여러 개인 경우는 위와 같이 표시해주고, 또 undefined 같은 값을 처리해주어야 할 때는
| undefined 형태로 작성해주면 된다.
//3
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
...과 같은 나머지 매개변수도 배열로 처리하여 받아준당.
//4
interface User{
name:string;
}
const Sam : User={name:'Sam'}
//아래는 두개의 매개변수를 지정하는 함수라고 할 수 있다.
function showName(this:User, age:number, gender:'m'|'f'){ //this에도 타입을 설정해줘야함, 이때 매개변수는 2개임!
console.log(this.name,age,gender)
}
const a = showName.bind(Sam); //bind로 this를 Sam 객체로 강제하고 있음
a(30,'m');
bind를 통해 this를 Sam이라는 객체를 강조할 때엔
this의 타입 또한 지정해주어야 한다.
사용하고 싶은 프로퍼티를 품고, 강조하고 싶은 객체의 타입이 User이므로
this: User라고 명시해준다.
//5 함수 오버로드
interface User{
name:string;
age:number;
}
//함수 오버로드 -> 전달되는 값이나 객체에 따라 다르게 움직이게끔
function join(name:string,age:string):string; //age가 문장열이면 반환값도 그럴거라는 것임을 명시해줌
function join(name:string,age:number):User;
function join(name:string,age:number|string):User|string{ //벨류 객체
if(typeof age ==="number"){
return {
name,
age
};
}else{
return "나이는 숫자로 입력해주세요,";
}
}
const sam:User=join("Sam",30);
함수 오버로드란, 같은 함수이름을 가지지만 다른 매개변수와 리턴타입을 가지는 경우를 말한다.
타입스크립트에서도 위와 같이 객체나 전달값을 유동적으로 지정해줄 수 있다.
속성으로 배우기 위해 아래의 강좌를 참고했다.
10분짜리 8개로 되어있어서 호로록 듣기 편함
https://youtube.com/playlist?list=PLZKTXPmaJk8KhKQ_BILr1JKCJbR0EGlx0
'Web' 카테고리의 다른 글
프론트엔드 개발자가 바라볼 수 있는 웹 최적화 (0) | 2023.04.09 |
---|---|
[공유] 주니어 프론트엔드 엔지니어에서 벗어나는 방법 (0) | 2022.12.29 |
CSR와 SSR이란 무엇이고 차이점은? (0) | 2022.07.13 |
[Vue.js #6] Vue2 라우터 설치 오류 (ERESOLVE unable to resolve dependency tree) (0) | 2022.02.28 |
[Vue.js #5] 내가 보려고 쓴 Vue-cli 초기실행법 (Vue2) (0) | 2022.02.18 |