인터페이스 | 타입 별칭
2022. 12. 26. 15:42ㆍ프로그래밍/TypeScript
인터페이스 (interface)
타입스크립트 여러 객체를 정의하는 일종의 규칙/구조
interface 키워드 사용
? 사용 시 선택적 속성 정의 가능
interface User {
name: string,
readonly age: number, // 읽기 전용 속성 (readonly)
isValid?: boolean // 선택적 속성 (Optional property)
}
인터페이스 + 타입 단언
interface A {
name: string;
}
// 빈 객체로 초기화 하지만
// A의 구조로 변경될 것이라고 단언함
const a = {} as A;
// A의 구조로 변경
a.name = 'abcdefg...';
읽기 전용 속성
읽기 전용 속성 정의 가능
readonly 키워드 사용
// 모든 속성이 readonly일 경우
interface User {
name: string,
age: number
}
// 유틸리티 (Utility) 활용
const user: Readonly<User> = {
name: 'Neo',
age: 36
};
// 타입 단언 (Type Assertion) 활용
const user = {
name: 'Neo',
age: 36
} as const;
함수 타입
함수 타입의 인터페이스 정의 시 호출 시그니처 사용
호출 시그니처: 함수의 매개변수, 반환 타입 지정
interface Name {
// 호출 시그니처
(매개변수이름: 타입) : 반환타입
}
interface User {
name: string
}
// 함수 타입 인터페이스
interface GetUser {
// (매개변수이름: 타입): 반환타입
(name: string): User
}
const getUser: GetUser = name => {
...
return { name }
}
getUser('Neo');
클래스 타입
클래스 타입의 인터페이스 정의 가능
implements 키워드 사용
interface UserClass {
name: string,
getName(): string
}
class User implements UserClass {
constructor(public name: string) {
}
getName() {
return this.name;
}
}
const neo = new User('Neo');
neo.getName(); // Neo
정의한 클래스를 인수로 사용하는 경우 문제 발생
interface CatClass {
name: string;
}
class Cat implements CatClass {
constructor(public name: string) { }
}
function makeKitten(c: CatClass, n: string) {
return new c(n); // Error. 'CatClass' 형식에 구문 시그니처가 없음
}
const kitten = makeKitten(Cat, 'Lucy');
console.log(kitten);
구성 시그니처를 가진 인터페이스를 정의하여 해결 가능
interface Name {
// 구성 시그니처
new (매개변수이름: 타입): 반환타입
}
interface CatClass {
name: string;
}
// 구성 시그니처
interface CatConstructor {
// new (매개변수이름: 타입): 반환타입
new (name: string): CatClass;
}
class Cat implements CatClass {
constructor(public name: string) { }
}
function makeKitten(c: CatConstructor, n: string) {
return new c(n);
}
const kitten = makeKitten(Cat, 'Lucy');
console.log(kitten);
인덱싱 가능 타입 (Indexable types)
많은 속성을 가지거나
단언 불가능한 임의의 속성이 포함되는 구조에서 사용
인덱스 시그니처 사용
interface Name {
// 인덱스 시그니처
[인덱서이름: 타입]: 반환 타입
}
interface Item {
// 인덱스 시그니처
[item: number]: string
}
const item: Item = ['a', 'b', 'c'];
console.log(item[0]);
console.log(item['0']); // Error. 인덱스는 number 타입만 가능
// 반환 타입으로 유니언 활용
interface User {
[key: string]: string | boolean;
}
const user: User = {
name: 'Neo',
email: 'thesecon@gmail.com',
isValid: true,
0: false
};
// 인덱스: string
console.log(user['name']); // 'Neo'
console.log(user['email']); // 'thesecon@gmail.com'
console.log(user['isValid']); // true
// 인덱스: number
console.log(user[0]); // false
console.log(user[1]); // undefined
// 인덱스: string (해당하는 인덱스 값이 없음)
console.log(user['0']); // false
// 인덱스 시그니처 + 명시적으로 정의된 속성
interface User {
[key: string]: string | number
name: string,
age: number
}
const user: User = {
name: 'Neo',
age: 123,
// 인덱스: string, 값: string
email: 'thesecon@gmail.com',
// 인덱스: string, 값: boolean
isAdult: true // Error. string 또는 number 타입만 할당 가능
};
keyof
인덱싱 가능 타입에서 keyof 키워드를 사용하면
속성 이름을 타입으로 사용 가능
타입의 속성 이름들이 유니온 타입으로 적용됨
keyof를 통한 인덱싱으로 타입의 값에 접근 가능
interface Countries {
KR: '대한민국',
US: '미국',
CP: '중국'
}
// 속성 이름을 타입으로 사용 가능
let country: keyof Countries; // 'KR' | 'US' | 'CP'
country = 'KR';
// keyof를 통한 인덱싱으로 타입의 값에 접근 가능
let country: Countries[keyof Countries]; // Countries['KR' | 'US' | 'CP']
country = '대한민국';
인터페이스 확장
클래스처럼 extends 키워드로 상속 가능
같은 이름의 인터페이스 여러 개 정의 가능
기존 인터페이스와 중복되는 속성은 타입이 같아야 함
interface Animal {
name: string;
}
interface Cat extends Animal {
meow(): string;
}
class Cat implements Cat {
constructor(public name: string) {}
meow() {
return 'MEOW~';
}
}
const cat = new Cat('Luxy');
interface FullName {
firstName: string,
lastName: string
}
// 같은 이름의 인터페이스 여러 개 정의 가능
interface FullName {
middleName: string,
// 기존 인터페이스와 중복되는 속성은 타입이 같아야 함
lastName: boolean // Error. string 타입이어야 함
}
const fullName: FullName = {
firstName: 'Tomas',
middleName: 'Sean',
lastName: 'Connery'
};
타입 별칭 (Type Aliases)
type 키워드를 사용해 새로운 타입 조합을 만들 수 있음
하나 이상의 타입을 조합해 이름을 부여함
조합한 각 타입들을 참조하는 별칭을 만드는 것
// MyType 이라는 이름을 가진 string 타입
type MyType = string;
// YourType 라는 이름을 가진 유니언 타입
type YourType = string | number | boolean;
// string 타입의 매개변수를 받음
// YourType 타입의 값을 반환함 (string | number | boolean)
function someFunc(arg: MyType): YourType {
switch (arg) {
case 's':
return arg.toString(); // string
case 'n':
return parseInt(arg); // number
default:
return true; // boolean
}
}
// User 라는 이름을 가진 유니언 타입
type User = {
name: string,
age: number,
isValid: boolean
} | [string, number, boolean]; // 튜플 타입
const userA: User = {
name: 'Neo',
age: 85,
isValid: true
};
const userB: User = ['Evan', 36, false];