인프런 캡틴판교님의 타입스크립트 입문 - 기초부터 실전까지 강의를 들으며 공부한 내용입니다.
// 문자열
const str: string = 'hello';
// 숫자
const num: number = 10;
// 배열
const arr: Array<string> = [];
arr.push('hi');
// 배열 - 리터럴 적용
const items: string[] = [];
// items.push(10);
// 튜플
const address: [string, number] = ['판교', 40];
// 객체
const obj: object = {};
// obj.a = 10;
// 타입 객체
const person: { age: number; name: string } = { age: 100, name: 'Capt' };
person.age = 101;
// 진위값
let isLogin: boolean = false;
interface User {
age: number
name: string
}
const seho: User = {
age: 33,
name: '세호',
}
// 함수에 인터페이스 활용
// 인자에다가 User라는 interface를 쓴다는 것은 특정형식을 준수하는 데이터만 받겠다고 정의를 한 형태
// parameter에다가 인터페이스를 정의하고 함수를 호출할 때 인자가 파라미터에 정의한 인터페이스의 규칙을 잘 따르는지까지 확인해주는 것이 타입스크립트의 역할이고
// 인터페이스의 장점이다
function getUser(user: User) {
console.log(user)
}
const sun = {
name: '해',
age: 100,
}
getUser(sun)
//함수의 스펙(구조)에 인터페이스를 활용
interface SumFunction {
(a: number, b: number): number
}
// 인자 a와 b는 number 타입이고 반환값의 타입도 number다
let sum2: SumFunction
sum2 = function (a: number, b: number): number {
return a + b
}
// sum2를 선언하면서 interface를 지정해주고 sum2에 함수를 지정할 때 이전에 지정했던 인터페이스의 타입과 동일하게 설정을 해주어야한다
// 인덱싱
interface StringArray {
[index: number]: string
}
var arr = ['a', 'b', 'c']
arr[0] //'a'
//인터페이스 확장
// 디벨로퍼 중복되는 값들을 다른 인터페이스가 가지고있다고 하면 갖고있는 속성과 타입을 상속을 받을 수 있다
interface Person {
name: string
age: number
}
interface Developer extends Person {
language: string
}
var captain: Developer = {
language: 'ts',
age: 100,
name: '캡틴',
}
Type Aliases (타입 별칭)
특정 타입이나 인터페이스를 참조할 수 있는 타입 변수
// string type사용
const name: string = 'capt';
// 타입 별칭을 사용할 때
type MyName = string;
const name: Myname = 'capt';
interface Person_I {
name: string
age: number
}
type Person_T = {
name: string;
age: number;
}
var sehoo: Person_I = {
name: '세호',
age: 30
}
타입은 extends 불가능
interface extends는 가능
TS 공식문서에서 interface 사용을 추천
or
을 이용하여 여러개의 타입 지정하기
function logMessage(value: string | number) {
console.log(value);
}
function logMessage2(value: string | number) {
if(typeof value === 'number'){
value.toLocaleString();
}
}
이러한 방식은 타입가드라고 부를 수 있다
타입 가드 : 특정 타입으로 타입의 범위를 좁혀나가는(필터링 하는)과정
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function askSomeone(someone: Developer | Person){
someone.name
}
인터페이스같은 특정 구조체를 여러개 유니온 타입으로 설정할 시에는 공통 된 속성만 접근할 수 있다
위와 같은 경우에는 name 속성에만 접근이 가능하다
function askSomeone(someone: Developer & Person){
someone.name
}
askSomeone({name: 'name', skill : 'skill', age: 1});
& 로 연결할 경우 포함하는 새로운 타입을 만들게 된다
특정 값들의 집합을 의미하는 자료형
숫자형 이넘
enum Shoes{ Nike, Adidas } var myShoes = Shoes.Nike; console.log(myShoes); // 0
값에 특정값을 할당하거나 초기화를 하지 않는다면
기본값들은 자동으로 숫자로 증가하게 됨Nike = 10 Adidas // 11 자동증가 됨
문자형 이넘
enum Shoes{ Nike = '나이키', Adidas = '아디다스' } var myShoes = Shoes.Nike; console.log(myShoes); // 나이키
//활용 예제
enum Answer{
Yes = 'Y',
No = 'N',
}
function askQuestion(answer: Answer){
if(answer === Answer.Yes)
...
}
enum으로 제공되는 값만 적용해서 비교할 수 있다(ex:드롭다운)
function getText<T>(text: T): T {
return text;
}
getText<string>('hi');
function getText<string>(text: string): string {
return text;
}
함수를 호출하면서 전달하는 타입의 값이 지정해준 제네릭자리에 다 들어간다
파라미터의 타입을 지정하면서 넘겨준다
function logText(text: string) {
console.log(text);
return text;
}
function logNumber(num: number) {
console.log(num);
return num;
}
같은 작업을 하는 코드를 타입을 다르게 받는다는 이유로 위와 같이 작성하게 된다면
유지보수 측면에서도 굉장히 안좋은 코드로 취급된다
interface Dropdwon {
value: string;
selected: boolean;
}
const obj_1: Dropdwon = {value: 'abc', selected: false};
interface GenericDropdwon<T>{
value: T;
selected: boolean;
}
const obj_2: GenericDropdwon<string> = {value: 'abc', selected: false};
// 유니온방식
function createDropdownItem(item: DropdownItem<string> | DropdownItem<number>)
emails.forEach(function (email) {
const item = createDropdownItem(email);
});
// 제네릭방식
function createDropdownItem<T>(item: DropdownItem<T>)
emails.forEach(function (email) {
const item = createDropdownItem<string>(email);
}
제네릭의 타입 제한 1 - (타입에 대한 힌트주기)
ts입장에서는 어떤 타입이 알수가 없기때문에 length라는 프로퍼티에대한 에러가 난다function logTextLength<T>(text: T): T{ console.log(text.length); return text; } //함수 안에서는 제네릭의 타입이 배열이라는것을 알고 있기 때문에 배열이라 가정을 하고 그 외 속성이나 API를 제공한다 function logTextLength<T>(text: T[]): T[]{ console.log(text.length); text.forEach((el) => { console.log(el) }) return text; }
제네릭 타입 제한 2 - 정의된 타입 이용하기 (하위호환)
interface LengthType { length: number; } function logTextLength<T extends LengthType>(text: T): T{ text.length; return text; } logTextLength({length: 10});
제네릭 타입제한 3 - keyof
이미 지정해놓은 타입 중에서만 어떤것을 받을지 제한하기interface ShoppingItem { name: string; price: number; stock: number; } // ShoppingItem에 있는 키 중에 한가지가 제네릭이 된다 // 파라미터로는 name, price, stock 중 한가지가 된다 function getShoppingItemOption<T extends keyof ShoppingItem>(itemOption: T): T{ return itemOption; } getShoppingItemOption('name')