타입스크립트의 고유 기능들
인터페이스
- JavaScript에서는 존재하지 않는다.
- 객체의 타입을 정의하고 생김새를 가지도록 할 수 있다.
- TypeScript에서의 클래스 기능은 C#에서 유래된 것이 많다.
- 일부 기능은 TS에서만 존재하는 고유 문법으로 컴파일 후에 사라진다.
extends
가 아닌implements
키워드로 구현한다.
/**
* 인터페이스
*
* interface
* - 정의
* - 설계
*
* implements
* - 구현
*/
interface Person {
name: string
age: number
}
const jang: Person = {
name: 'Jang',
age: 99
}
implements
- interface의 설계를 구현한다
/**
* interface implements
*/
interface Animal {
name: string
run(): string
}
interface Person {
sayName(): string
}
class AnyClass {
}
//여러 개를 implement 가능, 클래스 확장도 가능
class Jang extends AnyClass implements Animal, Person {
constructor(public name: string) {
super()
}
run() {
return this.name
}
sayName() {
return `사람의 이름은 ${this.name}`
}
}
extends
- 인터페이스끼리 확장 가능 - 충돌 주의!
/**
* interface extends
*/
interface Animal {
name: string
run(): string
}
//인터페이스끼리도 확장 가능 - 충돌 주의!
interface Person extends Animal {
sayName(): string
}
const jang: Person = {
name: 'Jang',
run() {
return 'string'
},
sayName() {
return 'string2'
}
}
타입 가드
typeof
- JavaScript에서 이미 존재하는 타입 검사 연산자
- typeof 연산자는 피연산자의 자료형을 문자열로 반환
/**
* typeof
*/
function print(value: number | string): string {
if (typeof value === 'number') {
return String(value)
}
if (typeof value === 'string') {
return value
}
return value
}
in
- JavaScript에서 객체가 특정 속성(Array 등)을 가지고 있는지 검사해 결과를 boolean으로 반환한다.
/**
* in 연산자
*/
interface Dog {
name: string
bark(): '멍멍'
}
interface Cat {
name: string
meow(): '냐옹'
}
function sayAnimal(animal: Dog | Cat) {
if ('bark' in animal) {
animal.bark()
animal.name
}
if ('meow' in animal) {
animal.meow()
}
}
instanceof
- JS에서 이미 존재하는 키워드
- 생성자의 prototype 속성이 객체의 prototype 체인 어딘가 존재하는지 판별
- typeof처럼 사용 가능
/**
* instanceof
*/
function getDate(date: Date | string): Date {
if (date instanceof Date) {
return date
}
return new Date(date)
}
사용자 정의
- 사용자 정의 타입 가드
- '매개변수 is 타입' 형태로 사용
/**
* 사용자 정의 타입 가드
*
* 매개변수 is 타입
*/
function isDate(date: Date | string): date is Date {
return date instanceof Date
}
function getDate(date: Date | string): Date {
if (isDate(date)) {
return date
}
return new Date(date)
}
interface Dog {
name: string
bark(): '멍멍'
}
interface Cat {
name: string
meow(): '냐옹'
}
function isDog(animal: Dog | Cat): animal is Dog {
return 'bark' in animal
}
function isCat(animal: Dog | Cat): animal is Cat {
return 'meow' in animal
}
function sayAnimal(animal: Dog | Cat) {
if (isDog(animal)) {
animal.bark()
}
if (isCat(animal)) {
animal.meow()
}
}
열거형
- 의미있는 상수 자료를 정의할 수 있다.(문서화)
- 키를 값에 할당하며 순서가 없는 집합이자 자료구조이다.
- enum 키워드 + PascalCase 조합으로 생성한다.
- 계산된 값을 사용할 수 있다. -> TypeScript가 알아서 추론
- enum은 컴파일 후에도 JavaScript에 함수형태로 남는다!
/**
* 열거형 (Enum)
*/
enum Prize {
Gold = 100,
Silver, //101
Bronze //102
}
interface Inter {
name: 'name'
}
// console.log(Inter.name)
// console.log(Prize)
console.log(Prize.Gold)
console.log(Prize['Gold'])
숫자형 열거
/**
* 숫자 열거형 (Enum)
*/
enum Prize {
Gold = 500,
Silver = 600,
Bronze = 700,
}
enum Order {
First = 1,
Second, //2
Third, //3
}
문자형 열거
- 각 멤버의 값은 문자열로 초기화되어야 한다.
- 숫자형 열거와 동작 방식이 다르다.
- 값이 자동으로 증가하지 않는다.
- 이외에 리버스 매핑 가능 여부등의 차이점도 존재한다.
/**
* 문자 열거형 (Enum)
*/
enum Prize {
Gold = 'Gold',
Silver = 'Silver',
Bronze = 'Bronze',
}
console.log(Prize)
console.log(Prize.Gold)
console.log(Prize['Bronze'])
혼합형 열거
/**
* Heterogeneous 열거형 (혼합)
* 되긴 되는데 굳이...?
*/
enum Dummy {
First = 0,
Silver = 'Silver',
}
enum BoolLikeEnum {
No = 0,
Yes = 'YES',
}
리버스 매핑
- 숫자형 열거의 경우 키와 값을 역으로 매핑할 수 있다.
- 문자형 열거는 지원되지 않음
/**
* 리버스 매핑 (역방향 찾기)
*/
enum Order {
// name = value
First = 1,
Second = 2,
Third = 3,
}
const firstVal = Order.First
const keyOfFirstVal = Order[firstVal]
console.log(firstVal)
console.log(keyOfFirstVal)
// enum OrderStr {
// First = 'First',
// Second = 'Second',
// Third = 'Third',
// }
// console.log(Order)
// console.log(OrderStr)
const 열거
- 기본적으로 열거형은 불안전한 접근을 허용한다.
- const enum은 이러한 점을 보완하기 위한 안전한 열거형이다.
- enum 앞에 const 키워드를 명시하여 사용
- 컴파일 후 제거되기 때문에 enum과 달리 JavaScript 코드를 생성하지 않는다.
/**
* const 열거
*/
const enum Desk {
Color = 'White',
Width = 1400,
}
Desk.Color
// Desk.Height
// Desk['Height'] //const 없을 시 다른 에러 발생!(cannot find name 'Height') -> 불안전한 접근
열거형 활용
- 열거형은 런타임에 존재하는 실제 객체
- keyof, keyof typeof 와 조합하여 활용할 수 있다.
/**
* 열거형 활용
*/
const enum Language {
TypeScript = 'TS',
JavaScript = 'JS',
Java = 'JAVA',
Ruby = 'RB',
}
const Language2 = {
TypeScript: 'TS',
JavaScript: 'JS',
Java: 'JAVA',
Ruby: 'RB',
} as const //read only
type LangCode = keyof typeof Language
// 위와 아래가 같다
type LangCode2 = "TypeScript" | "JavaScript" | "Java" | "Ruby"
function getLang(langCode: LangCode) {
console.log(langCode)
}
논리 연산자 활용 타입
타입 별칭
- 의미없는 반복을 줄이고 타입을 명시적으로 사용하도록 돕는다.
- let, const를 선언해 변수를 초기화 하듯 사용할 수 있다!
- 컴파일러가 따로 추론하지는 않는다(인터페이스와의 차이점)
/**
* Type Aliases (타입 별칭)
*/
type str = string
type num = number
type arr = num[]
type func = () => void
type Person = {
name: str
age: num
counts: arr
getInfo: func
}
//인터페이스는 타입 추론 등 다양한 기능이 있다
interface PersonInterface {
name: str
age: num
counts: arr
}
Union Type
- 둘 중 하나(or 연산)
- 아주 유용하다!
/**
* Union 타입 (합집합)
*/
type StringOrNumber = string | number
type GenderType = 'M' | 'F'
const a:StringOrNumber = 'STR'
const b:StringOrNumber = 123
// const c:StringOrNumber = boolean
type Person = {
name: string
age: number
}
type Me = {
name: string
genderType: GenderType
}
const obj: Person | Me = {
name: 'Jang',
age: 99,
genderType: 'M'
}
Intersection Type
- 두 타입의 공통(교집합)
- 잘은 안 쓴다..
/**
* Intersection 타입 (교집합)
* - 둘의 공통 분모
* - 잘은 안 씀..
*/
type StringAndNumber = string & number
type GenderType = 'M' | 'F'
// const a:StringAndNumber = 'STR'
// const b:StringAndNumber = 123
// const c:StringAndNumber = boolean
type Person = {
name: string
age: number
}
type Me = {
name: string
generType: GenderType
}
const obj: Person & Me = {
name: 'Jang',
age: 99,
generType: 'M' //하나라도 없으면 에러 발생!
}
유니온 타입 판별
- 추론하기 어려운 유니온 타입을 추론하기 위함
- 적절한 타입 가드 사용
- 무분별한 유니온 타입 사용 지양
/**
* 유니온 타입 판별
*/
interface Male {
name: string
age: number
genderType: 'M'
}
interface Female {
name: string
age: number
genderType: 'F'
}
type Person = Male | Female
function createMale({ name, age, genderType }: Person): Male {
return {
name, age, genderType
}
}
function createFemale({ name, age, genderType }: Person): Female {
return {
name, age, genderType
}
}
'Dev > JS Family, HTML, CSS' 카테고리의 다른 글
[React] 리액트 심화 - SPA, React Router, 비동기 프로그래밍 (0) | 2022.09.16 |
---|---|
[TypeScript] 타입스크립트 입문 (4) - 제네릭, 고급 타입 다루기 (0) | 2022.09.14 |
[TypeScript] 타입스크립트 입문 (2) - 기본 타입, 클래스 (0) | 2022.09.09 |
[TypeScript] 타입스크립트 입문(1) (2) | 2022.09.04 |
[React] 일주일만에 리액트 정복하기! (2) (0) | 2022.08.03 |