인터페이스(Interface)
- 개체(객체, 배열, 함수, 클래스 등)을 정의하는 타입
- ? 나 readonly 사용 가능 (type , interface 둘다 가능)
? 속성
- 있어도 되고 없어도 되는 선택적 의미
interface User1 {
name: string;
age: number;
isValid?: boolean;
}
const user: User1 = {
name: "BAEK",
age: 27,
};
type UserT = {
name: string;
age: number;
isValid?: boolean;
};
const user: UserT = {
name: "BAEK",
age: 27,
};
readonly 속성
- 읽기전용 속성을 만들 때 사용한다
interface User1 {
name: string;
readonly age: number;
isValid?: boolean;
}
const user: User1 = {
name: "BAEK",
age: 27,
};
user.age = 22; // 에러 발생 => readonly 속성이기 때문에 바뀌지 않는다
인터페이스의 함수와 클래스타입
함수 - 호출 시그니처(Call signiture)
- interface 함수명 {매개변수 : 매개변수타입 ) : 반환타입
interface User {
name: string;
age?: number;
}
type GetUserNameT = (u: User) => string;
interface GetUserNameI {
(u: User): string; // 호출 시그니처
}
const user: User = {
name: "BAEK",
};
const getUserName: GetUserNameI = (user: User) => user.name;
const username = getUserName(user);
console.log(username); // BAEK
클래스 - 생성(구문) 시그니처(Construct signature)
- interface 타입명 { new (매개변수 : 매개변수타입) : 반환타입 }
interface IUser {
name: string;
getName(): string; // 객체 내의 '메소드'를 정의할땐 이름옆에 () 를 붙인다.
} // 정확하게 클래스의 속성이라기 보단, 클래스에서 만들어지는 인스턴스의 속성
class User implements IUser {
// class 클래스명 implements 클래스 인스턴스 타입
public name; // 아래 this.name에서 접근할 값.
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
}
const user = new User("BAEK");
user.getName();
function hello(userClass: User, msg: string) {
// userClass의 타입을 User 로 지정하면 에러 발생 -> User형식에 구문 시그니처가 없기 때문
// IUser 여도 동일
const user = new userClass("BAEK");
return `Hello ${user.getName()}, ${msg}`;
}
hello(User, "good morning");
// User라는 클래스 자체를 매개변수로 씀
위의 코드에서 "User 클래스에 구문 시그니처가 없다"라는 에러가 발생하기 때문에 구문 시그니처를 만들어 해결한다
함수 시그니처 처럼 () : 타입 형태이지만, 생성 시그니처니까 앞에 new 키워드를 붙인다
interface IUser {
name: string;
getName(): string; // 객체 내의 '메소드'를 정의할땐 이름옆에 () 를 붙인다.
} // 정확하게 클래스의 속성이라기 보단, 클래스에서 만들어지는 인스턴스의 속성
interface UserC {
// 구문 시그니처
new (n: string): IUser; // new 키워드
}
class User implements IUser {
// class 클래스명 implements 클래스 인스턴스 타입
public name; // 아래 this.name에서 접근할 값.
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
}
const user = new User("BAEK");
user.getName();
function hello(userClass: UserC, msg: string) {
// 구문 시그니처 적용
const user = new userClass("BAEK");
return `Hello ${user.getName()}, ${msg}`;
}
hello(User, "good morning");
// User라는 클래스 자체를 매개변수로 씀
인터페이스의 인덱싱 가능 타입
인덱싱 가능 - 인덱스 시그니처(Index signature)
- interface 타입명 { [매개변수 : 매개변수타입] : 값 타입]}
// Array
interface Arr {
[key: number]: string; // 매개변수 키값이름은 자유
}
const arr: Arr = ["A", "B", "C"];
console.log(arr[1]); // 'b'
// Array-like
interface ArrLike {
[key: number]: string;
}
const arrLike: ArrLike = { 0: "A", 1: "B", 2: "C" };
console.log(arrLike[1]); // 'b' // 대괄호 표기법으로 인덱싱
// Object
interface Obj {
[key: string]: string; // 키가 문자일땐 문자로 정의
}
const obj: Obj = { a: "A", b: "B", c: "C" };
console.log(obj["b"]); // 'B' // 대괄호 표기법 가능, 문자형태로 인덱싱 해야한다.
console.log(obj.b); // 'B'
interface User {
[key: string]: number | string;
name: string;
age: number;
}
const user: User = {
name: "BAEK",
age: 27,
};
console.log(user["age"]); // 27
function getValues(payload: unknown) {
// 객체데이터를 받아서 그의 값들만 반환하는 함수
if (payload && payload.constructor === Object) {
return Object.keys(payload).map((key) => payload[key]);
}
}
getValues(user); // ['BAEK', 27]
위의 코드에서는 payload[key]에 에러가 발생하는데 이유는 unknown 타입이기 때문에 인덱스 시그니처가 없는 상태이다. 따라서 인덱스 시그니처를 가지도록 만들어줘야 하기 한다.
interface Payload {
[key: string]: unknown;
}
function getValues(payload: Payload) {
// 객체데이터를 받아서 그의 값들만 반환하는 함수
if (payload && payload.constructor === Object) {
return Object.keys(payload).map((key) => payload[key]);
}
}
getValues(user); // ['BAEK', 27]
타입 인덱싱
interface User {
name: string;
age: number;
}
// interface로 선언한 타입에 대괄호 표기 사용 가능
const a: User["name"] = "BAEK"; // User["name"] => string
const b: User["age"] = "123"; // 에러 발생 => number 타입을 지정해야 한다
const c: User["age"] = 28; // User["age"] => number
인터페이스 확장
- interface 인터페이스1 extends 인터페이스2 { }
interface UserA {
name: string;
age: number;
}
interface UserB extends UserA {
isValid: boolean;
}
const user: UserB = {
name: "BAEK",
age: 27,
isValid: true,
};
- 중복 선언은 덮어지는 것이 아니라 합쳐진다 또는 병합한다라고 볼 수 있다
interface User {
name: string;
age: number;
}
interface User {
isValid: boolean;
}
const user: User = {
name: "BAEK",
age: 27,
isValid: true,
};
'📘 TypeScript' 카테고리의 다른 글
TypeScript - 함수의 오버로딩 (0) | 2023.11.21 |
---|---|
TypeScript - 함수의 명시적 this 타입 (0) | 2023.11.21 |
TypeScript - 타입 별칭(Alias) (0) | 2023.11.20 |
TypeScript - 타입 가드(Guard) (0) | 2023.11.20 |
TypeScript - 타입, 할당 단언(Assertion) (0) | 2023.11.20 |
인터페이스(Interface)
- 개체(객체, 배열, 함수, 클래스 등)을 정의하는 타입
- ? 나 readonly 사용 가능 (type , interface 둘다 가능)
? 속성
- 있어도 되고 없어도 되는 선택적 의미
interface User1 {
name: string;
age: number;
isValid?: boolean;
}
const user: User1 = {
name: "BAEK",
age: 27,
};
type UserT = {
name: string;
age: number;
isValid?: boolean;
};
const user: UserT = {
name: "BAEK",
age: 27,
};
readonly 속성
- 읽기전용 속성을 만들 때 사용한다
interface User1 {
name: string;
readonly age: number;
isValid?: boolean;
}
const user: User1 = {
name: "BAEK",
age: 27,
};
user.age = 22; // 에러 발생 => readonly 속성이기 때문에 바뀌지 않는다
인터페이스의 함수와 클래스타입
함수 - 호출 시그니처(Call signiture)
- interface 함수명 {매개변수 : 매개변수타입 ) : 반환타입
interface User {
name: string;
age?: number;
}
type GetUserNameT = (u: User) => string;
interface GetUserNameI {
(u: User): string; // 호출 시그니처
}
const user: User = {
name: "BAEK",
};
const getUserName: GetUserNameI = (user: User) => user.name;
const username = getUserName(user);
console.log(username); // BAEK
클래스 - 생성(구문) 시그니처(Construct signature)
- interface 타입명 { new (매개변수 : 매개변수타입) : 반환타입 }
interface IUser {
name: string;
getName(): string; // 객체 내의 '메소드'를 정의할땐 이름옆에 () 를 붙인다.
} // 정확하게 클래스의 속성이라기 보단, 클래스에서 만들어지는 인스턴스의 속성
class User implements IUser {
// class 클래스명 implements 클래스 인스턴스 타입
public name; // 아래 this.name에서 접근할 값.
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
}
const user = new User("BAEK");
user.getName();
function hello(userClass: User, msg: string) {
// userClass의 타입을 User 로 지정하면 에러 발생 -> User형식에 구문 시그니처가 없기 때문
// IUser 여도 동일
const user = new userClass("BAEK");
return `Hello ${user.getName()}, ${msg}`;
}
hello(User, "good morning");
// User라는 클래스 자체를 매개변수로 씀
위의 코드에서 "User 클래스에 구문 시그니처가 없다"라는 에러가 발생하기 때문에 구문 시그니처를 만들어 해결한다
함수 시그니처 처럼 () : 타입 형태이지만, 생성 시그니처니까 앞에 new 키워드를 붙인다
interface IUser {
name: string;
getName(): string; // 객체 내의 '메소드'를 정의할땐 이름옆에 () 를 붙인다.
} // 정확하게 클래스의 속성이라기 보단, 클래스에서 만들어지는 인스턴스의 속성
interface UserC {
// 구문 시그니처
new (n: string): IUser; // new 키워드
}
class User implements IUser {
// class 클래스명 implements 클래스 인스턴스 타입
public name; // 아래 this.name에서 접근할 값.
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
}
const user = new User("BAEK");
user.getName();
function hello(userClass: UserC, msg: string) {
// 구문 시그니처 적용
const user = new userClass("BAEK");
return `Hello ${user.getName()}, ${msg}`;
}
hello(User, "good morning");
// User라는 클래스 자체를 매개변수로 씀
인터페이스의 인덱싱 가능 타입
인덱싱 가능 - 인덱스 시그니처(Index signature)
- interface 타입명 { [매개변수 : 매개변수타입] : 값 타입]}
// Array
interface Arr {
[key: number]: string; // 매개변수 키값이름은 자유
}
const arr: Arr = ["A", "B", "C"];
console.log(arr[1]); // 'b'
// Array-like
interface ArrLike {
[key: number]: string;
}
const arrLike: ArrLike = { 0: "A", 1: "B", 2: "C" };
console.log(arrLike[1]); // 'b' // 대괄호 표기법으로 인덱싱
// Object
interface Obj {
[key: string]: string; // 키가 문자일땐 문자로 정의
}
const obj: Obj = { a: "A", b: "B", c: "C" };
console.log(obj["b"]); // 'B' // 대괄호 표기법 가능, 문자형태로 인덱싱 해야한다.
console.log(obj.b); // 'B'
interface User {
[key: string]: number | string;
name: string;
age: number;
}
const user: User = {
name: "BAEK",
age: 27,
};
console.log(user["age"]); // 27
function getValues(payload: unknown) {
// 객체데이터를 받아서 그의 값들만 반환하는 함수
if (payload && payload.constructor === Object) {
return Object.keys(payload).map((key) => payload[key]);
}
}
getValues(user); // ['BAEK', 27]
위의 코드에서는 payload[key]에 에러가 발생하는데 이유는 unknown 타입이기 때문에 인덱스 시그니처가 없는 상태이다. 따라서 인덱스 시그니처를 가지도록 만들어줘야 하기 한다.
interface Payload {
[key: string]: unknown;
}
function getValues(payload: Payload) {
// 객체데이터를 받아서 그의 값들만 반환하는 함수
if (payload && payload.constructor === Object) {
return Object.keys(payload).map((key) => payload[key]);
}
}
getValues(user); // ['BAEK', 27]
타입 인덱싱
interface User {
name: string;
age: number;
}
// interface로 선언한 타입에 대괄호 표기 사용 가능
const a: User["name"] = "BAEK"; // User["name"] => string
const b: User["age"] = "123"; // 에러 발생 => number 타입을 지정해야 한다
const c: User["age"] = 28; // User["age"] => number
인터페이스 확장
- interface 인터페이스1 extends 인터페이스2 { }
interface UserA {
name: string;
age: number;
}
interface UserB extends UserA {
isValid: boolean;
}
const user: UserB = {
name: "BAEK",
age: 27,
isValid: true,
};
- 중복 선언은 덮어지는 것이 아니라 합쳐진다 또는 병합한다라고 볼 수 있다
interface User {
name: string;
age: number;
}
interface User {
isValid: boolean;
}
const user: User = {
name: "BAEK",
age: 27,
isValid: true,
};
'📘 TypeScript' 카테고리의 다른 글
TypeScript - 함수의 오버로딩 (0) | 2023.11.21 |
---|---|
TypeScript - 함수의 명시적 this 타입 (0) | 2023.11.21 |
TypeScript - 타입 별칭(Alias) (0) | 2023.11.20 |
TypeScript - 타입 가드(Guard) (0) | 2023.11.20 |
TypeScript - 타입, 할당 단언(Assertion) (0) | 2023.11.20 |