npx create-react-app [폴더명] --template typescript
자바스크리브는 동적 타입(코드 실행시 알아서 변수타임을 표현) 언어로서 자유도가 높아 진입 장벽이 낮고 생산성이 높은 대신, 형식이 정해져 않기 때문에 오류(버그)가 런타임 중에 발생한다거나, 또는 팀원간의 소통의 오류가 단점으로 생겨난다
참(true)과 거짓(false)
let isDone: boolean = false;
let isShow: boolean = true;
console.log(isDone); // false
console.log(isShow); //true
정수와 실수의 구분 없이 사용
let num1: number = 7;
let num2: number = 0.6878;
console.log(num1); // 7
console.log(num2); // 0.6878
큰 따옴표(""), 작은 따옴표('')사용하여 문자열 데이터를 표현
let str: string = 'hello';
console.log(str); //hello
값들을 배열로 나열
/* 숫자형 배열의 타입을 정하는 2가지 방법 */
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
console.log(list1); // [1, 2, 3];
console.log(list2); // [1, 2, 3];
/* 문자형 배열의 타입을 정하는 2가지 방법 */
let list3: string[] = ['banana', 'apple', 'mango'];
let list4: Array<string> = ['banana', 'apple', 'mango'];
console.log(list3); // ['banana', 'apple', 'mango'];
console.log(list4); // ['banana', 'apple', 'mango'];
요소의 타입과 개수가 고정된 배열을 표현
let list5: [number, string, boolean] = [1, 'banana', true];
console.log(list5); // [1, 'banana', true];
객체의 프로퍼티 타입들을 각기 명시
let obj: object = {};
let obj2: { name: string; age: number; isDeveloper: boolean } = {
name: 'kimcoding',
age: 20,
isDeveloper: true,
};
console.log(obj);
console.log(obj2);
타입 검사를 하지 않고자 할때 사용 (사용을 권장 x)
//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;
}
let printAnswer = (): void => {
console.log("YES");
}
/* 1-1번 */
function sumNumber(a: number, b: number): number {
return a + b;
}
/* 1-2번 */
const sumNumber2 = (a: number, b: number): number => {
return a + b;
};
/* 2번 */
let sumString = (first: string, last: string): string => {
return `${first} ${last}`;
};
console.log(sumString('hi', 'codestates'));
/* 3번 */
let sumString2 = (first: string, last: string): string => {
return `${first} ${last}`;
};
//아래 코드도 동작하도록 구현해봅시다.
console.log(sumString2('hi', 'codestates'));
/* 4번 */
let printError = () => {
console.log('error message');
};
모든 타입에 공통인 멤버들에만 접근이 가능 (|연산자 사용
function getGift(gift: Car | Mobile){
// 조건문을 달지 않고 gift.name을 return하면 에러가 발생
// car에만 start()가 있기 떄문 -> 그래서 조건문을 달아줌
if(gift.name === "car") {
gift.start();
} else {
gift.call();
}
}
📍 타입가드란?
Typescript에서 타입을 보호하기 위해 사용되는 기능 중 하나로서 특정 코드 븍록에서 타입의 범위를 제한해 해당 코드 블록 안에서 타입 안정성을 보장해줌
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
// askSomeone 함수내부에서는 Developer와 Person이 갖고 있는
// 공통 프로퍼티인 name에만 접근할 수 있음
function askSomeone(someone: Developer | Person) {
console.log(someone.name);
}
function askSomeone(someone: Developer | Person) {
// in 연산자 : 타입스크립트에서 객체의 속성이 존재하는지를 체크하는 연산자
// in 연산자는 객체의 속성 이름과 함께 사용하여 해당 속성이 객체 내에 존재하는지 여부를 검사
if ('skill' in someone) {
console.log(someone.skill);
}
if ('age' in someone) {
console.log(someone.age);
}
}
둘 이상의 타입을 결합하여 새로운 타입을 만드는 방벙 (&연산자 사용)
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);
}
// 인터섹션 타입으로 결합하게 된다면 전달인자를 전달할때 선택지가 없음
// 유니온타입은 타입가드를 사용하면 선택지가 생김
askSomeone({name:'김코딩', skill:'웹 개발', age:20});
타입 체크를 위해 사용이 됨
interface User {
name: string;
age: number;
}
// 정상적으로 선언됩니다.
const user: User = {
name: "anna",
age: 20
}
// 프로퍼티의 순서를 지키지 않아도 정상적으로 선언됩니다.
const user: User = {
age: 20,
name: "anna"
}
// 정의된 프로퍼티보다 적게 작성했기 때문에 에러가 납니다.
const user: User = {
name: "anna"
}
// 정의된 프로퍼티보다 많이 작성했기 때문에 에러가 납니다.
const user: User = {
name: "anna",
age: 20,
job: "developer"
}
interface User {
name: string;
age: number;
job: string;
}
interface Greeting {
(user: User, greeting: string): string;
}
const greet: Greeting = (user, greeting) => {
return `${greeting}, ${user.name}! Your job : ${user.job}.`;
}
const user: User = {
name: "anna",
age: 30,
job: "developer"
};
const message = greet(user, "Hi");
console.log(message);
interface Calculator {
add(x: number, y: number): number;
substract(x: number, y: number): number;
}
class SimpleCalculator implements Calculator {
add(x: number, y:number) {
return x + y;
}
substract(x: number, y: number) {
return x - y;
}
}
const caculator = new SimpleCalculator();
console.log(caculator.add(4, 9)); // 13
console.log(caculator.substract(10, 5)); // 5
interface Todo {
id: number;
content: string;
isDone: boolean;
}
// Todo 인터페이스를 타입으로 받는 todos를 완성합니다.
let todos: Todo[] = [];
// Todo 인터페이스를 타입으로 받는 addTodo를 완성합니다.
function addTodo(todo: Todo): void {
todos = [...todos, todo];
}
// Todo 인터페이스를 타입으로 받는 newTodo를 완성합니다.
const newTodo = {
id: 1,
content: 'learn typescript',
isDone: false,
};
addTodo(newTodo);
console.log(todos);
클래스 확장할때 extends라는 키워드를 사용해 기존에 존재하던 클래스를 상속해 새로운 클래스를 정의
interface Person {
name: string;
age: number;
}
interface Developer extends Person {
language: string;
}
const person: Developer = {
language: "TypeScript",
age: 20,
name: "Anna",
}
타입의 새로운 이름을 만드는 것
type MyString = string;
let str1: string = 'hello!';
// string 타입처럼 사용할 수 있습니다.
let str2: MyString = 'hello world!';
type Person = {
id: number;
name: string;
email: string;
}
//Commentary 인터페이스에서 Person 타입을 참조하고 있습니다.
interface Commentary {
id: number;
content: string;
user: Person;
}
//객체에서 Commentary 인터페이스를 참조하고 있습니다.
let comment1: Commentary = {
id: 1,
content: "뭐예요?",
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
},
}
//Commentary 인터페이스 내부에 content 프로퍼티가 존재하기 때문에
//content 프로퍼티를 작성하지 않으면 컴파일 에러가 납니다.
let kimcoding: Commentary = {
id: 1,
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
},
};
//Person 타입 내부에 isDeveloper 프로퍼티가 존재하지 않기 때문에
//isDeveloper 프로퍼티를 작성할 시 컴파일 에러가 납니다.
let kimcoding: Commentary = {
id: 1,
content: "뭐예요?",
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
isDeveloper: true,
},
};