솔미는 성장중
[TS 1주차] 타입스크립트 본문
🌞 타입스크립트란?
정적 타입의 컴파일 언어
: 코드 작성 단계에서 타입 오류를 확인할 수 있다!
JS로 컴파일 후 브라우저나 Node.js환경에서 동작한다.
타입스크립트는 자바스크립트의 '슈퍼셋' = 완벽 호환
ts는 js기능의 모든 기능을 포함하고 있고 +a가 있다!
🌞 타입스크립트는 왜 써야할까?
1. 에러의 사전 방지
ex) 인자의 타입 지정 가능.
2. 코드 가이드 및 자동 완성
단점1. 적지 않은 학습 비용 : 타입 시스템의 이해, 기반 환경 이해 ...
단점 2. 운영 중인 서비스 적용에 대한 부담감
타입스크립트 대안 JSDoc
: 코드가 길어질 수 있다는 단점을 갖고 있지만 JSDoc으로 타입스크립트가 가진 장점을 흉내낼 수 있음.
🌞 타입스크립트에서 '인터페이스'의 의미는?
객체 타입을 정의할 때 사용하는 문법.
인터페이스를 통해 객체의 속성과 속성 타입, 함수의 파라미터와 반환 타입, 함수의 스펙, 배열과 객체를 접근하는 방식, 클래스를 정의할 수 있다.
인터페이스에서 this 사용법
인터페이스에서 this 사용법
(명식적 this)
interface Cat {
name: string
age: number
}
const cat: Cat = {
name: 'Lucy'
age: 3
}
function hello(this:Cat, message: string){ //message는 매개변수. this는 타입을 지정해주기 위한 문법.(매개변수x)
console.log(`Hello ${this.name}, ${message}`)
}
hello.call(cat, 'You are awesome')
🌞 인덱스 시그니처란?
배열과 객체의 인덱싱 타입을 정의할 때 속성 이름을 정확히 명시하지 않고 속성 이름의 타입과 속성 값의 타입을 정의하는 문법.
객체와 배열을 인덱싱할 때 활용될 뿐만 아니라 객체의 속성 타입을 유연하게 정의할 때도 사용됨.
객체의 속성 이름 & 속성 값이 정해져 있으면 명시해서 정의하고 구체적으로 어떤 속성이 제공될지 알 수 없을 때 적용하면 좋다.
장점: 아래 예시에서 속성 이름이 문자열 & 속성 값이 문자열이기만 한다면 모두 추가할 수 있다!
ex)
interface SalaryInfo {
[level: string]: stirng;
}
let salary: SalaryInfo = {
junior: '1원',
senior: '2원',
ceo: '3원'
}
ex) 인덱스 시그니처가 있어서 아래 형식으로 객체를 추가하는 것이 가능
interface User {
[key: string]: unknown,
name: string,
age: number
}
const solmi: User = {
name: 'Solmi',
age: 100,
}
solmi['isValid'] = true;
solmi['emails'] = ['ovo10203@gmail.com', 'example@gmail.com']
console.log(solmi)
/*
name:'Solmi'
age: 100
isValid: true
emails: (2) ['ovo10203@gmail.com', 'example@gmail.com']
*/
ex)
interface Payload {
[key: string]: unknown
}
function logValues(payload: Payload){
for(const key in payload){ //객체데이터를 반복하는 for in 문
console.log(payload[key]
}
}
interface User {
[key: string]: unknown //이게 있어야 오류가 안난다!!
name: string
age: number
isValid: boolean
}
const solmi: User = {
name: 'Solmi',
age: 100,
isValid: true
}
logValues(solmi)
🌜 객체 안에 key과 속성값 세트가 모두 같은 데이터 형식을 갖지 않을 수도 있잖아!
그러면 어떻게 표현?
ex) 아래 객체 데이터에 대한 User라는 인터페이스를 만들어보는 상황
let solmi: User = {
id: 'nickname',
name: '솔미',
22: false
}
1번째 시행착오: 잘못된 방식)
인덱스 시그니처를 2개 이상 써서 표현하고자 했다. (2개를 쓰는 것 자체가 틀린 것은 아님. 2번째 시행착오 참고)
interface User {
[property: string]: string;
[property2: number]: boolean;
id: string;
}
let solmi: User = {
id: 'nickname',
name: '솔미',
22: false
}
하지만 위 코드는 틀린 코드이다. (인덱스 시그니처를 2개 이상쓸 땐 주의할 점이 있다. 아래 이유 및 더보기 참고)
'number' 인덱스 유형 'boolean'을(를) 'string' 인텍스 유형 'string'에 할당할 수 없습니다.ts(2413)
라는 오류가 뜬다.
=> 이유
색인의 타입으로는 문자열 또는 숫자만이 사용 가능하다. 이 때 주의해야 할 점은 만약 문자열과 숫자를 모두 인덱스 시그니처로 사용할 경우, 숫자로 색인 된 값의 타입은 문자열로 색인 된 값 타입의 서브타입이어야 한다는 것이다
(“B가 A의 서브타입이다” = “B 타입의 모든 값은 A 타입에도 속한다” )
이러한 제약이 존재하는 이유에 대한 자세한 설명이 궁금하다면! -> 더보기 참고
이러한 제약이 존재하는 이유 (더 자세한 설명)
자바스크립트 색인의 동작 방식 때문!!
자바스크립트 코드에서 객체의 색인에 접근할 때, 내부적으로는 색인의 toString() 메소드를 호출해 문자열로 변형된 값을 색인으로 사용한다. 예를 들어 1.toString() === '1' 이므로 obj[1] 이라고 적은 코드는 실제로는 obj['1']와 동일하다.
interface ErrorProne {
[str: string]: number;
[num: number]: boolean;
}
let errorProne: ErrorProne = {
'abc': 3,
3: true
};
errorProne[3];
2번째 시행착오: 옳은 방식)
interface User {
[property: string]: string|boolean;
[property: number]: boolean;
id: string;
}
let solmi: User = {
id: 'nickname',
name: '솔미',
22: false
}
인덱스 시그니처를 2개 이상 써서 표현하고자 했다.
숫자로 색인된 값의 타입(boolean)이 문자열로 색인된 값의 타입(string또는 boolean)이여서 에러가 발생하지 않는다.
2번째 시행착오: 옳은 방식) 유니언 타입 사용하기
interface User {
[property: string|number]: boolean|string;
}
let solmi: User = {
id: 'nickname',
name: '솔미',
22: false
}
유니언 타입 사용시 주의사항)
🎈 Key 타입은 string, number, symbol, Template literal 타입만 가능하다!
🎈 동일한 Key를 여러 개 가질 수 없다. (ex. 22: false, 22:true)
🎈 존재하지 않는 속성을 접근하면 undefined가 뜬다. (ex. solmi.email)
'TypeScript' 카테고리의 다른 글
[TS] 타입 호환 (0) | 2023.08.31 |
---|---|
[TS] 타입 가드 (0) | 2023.08.30 |
[TS] 타입 단언 (0) | 2023.08.30 |
[TS 2주차] 제네릭이란 무엇인가! (+ 제네릭을 제한하려면..?) (0) | 2023.08.23 |
[TS 2주차] 타입 별칭 vs 인터페이스 : 차이점은 무엇이고, 무엇을 써야하는가! (0) | 2023.08.22 |