이 내용은 코드앙마의 타입스크립트 강좌를 정리해놓은 자료이다.
object 속성
let user:object;
user = {
name: 'xx',
age: 30
}
user를 object 타입으로 정의를 하고 콘솔에서 name을 찍어보면 에러가 발생한다.
console.log(user.name); // 에러 발생
object에는 특정 속성값에 대한 정보가 없기 때문이다.
이렇듯 property를 정의해서 나타낼 때는 인터페이스를 사용한다.
인터페이스 정의
interface User {
name : string;
age : number;
}
let user : User = {
name : 'xx',
age : 30
}
User 인터페이스를 정의하고 user 값을 사용해 보자.
user.age = 10; // 이건 문제가 없고
user.gender = "male"; // 이건 오류가 발생
이건 gender가 없어서 발생하는 문제이다.
interface User {
name : string;
age : number;
}
let user : User = {
name : 'xx',
age : 30
}
gender를 추가해보자. gender는 값이 있어도 되고 없어도 되는 optional로 처리를 해보자.
interface User {
name : string;
age : number;
gender?: string; // optional로 처리
}
let user : User = {
name : 'xx',
age : 30
}
user.age = 10;
user.gender = "male";
gender는 optional로 지정했기 때문에 gender가 없어도 되지만 gender가 있을 때는 string이어야 한다.
다음은 readonly property를 만들어보자. 읽기 전용이다.
interface User {
name : string;
age : number;
gender?: string;
readonly birthday : number; // 읽기전용으로 설정
}
let user : User = {
name : 'xx',
age : 30,
birthday : 2000,
}
user.age = 10;
user.gender = "male";
user.birthday = 1990; // 여기서 오류가 발생한다.
user.birthday에서 수정할 때 오류가 발생한다.
readonly는 생성할 때만 할당이 가능하고 그 이후 수정이 불가능하다.
그 다음은 학년별로 점수를 기록하고 싶다고 하자.
interface User {
name : string;
age : number;
gender?: string;
readonly birthday : number;
1? : string;
2? : string;
3? : string;
4? : string;
}
let user : User = {
name : 'xx',
age : 30,
birthday : 2000,
1 : 'A',
2 : 'B',
3 : 'C'
}
이렇게 각 학년별로 optional로 지정하면 특정 학년의 값을 할당할 수 있다.
이렇게 하지 말고 문자열 인덱스로 추가하는 방법을 알아보자.
interface User {
name : string;
age : number;
gender?: string;
readonly birthday : number;
[grade: number] : string;
}
let user : User = {
name : 'xx',
age : 30,
birthday : 2000,
1 : 'A',
2 : 'B'
}
이렇게 [grade:number] 형식으로 정의할 수 있다. grade가 의미있는 값은 아니고 number 타입의 임의의 변수를 의미한다. grade를 다른 문자열로 지정해도 상관없다.
그리고 [grade: number] : string에서 성적을 숫자로 받기에는 범위가 너무 넓다. 이럴 때 사용하는 것은 문자열 리터럴 타입이다.
type Score = 'A' | 'B' | 'C' | 'F'; // type을 지정
interface User {
name : string;
age : number;
gender?: string;
readonly birthday : number;
[grade: number] : Score; // Score로 변경
}
let user : User = {
name : 'xx',
age : 30,
birthday : 2000,
1 : 'A',
2 : 'B'
}
위에서 grade를 Score로 변경한다. Score에 해당하는 값만 넣을 수 있다.
인터페이스로 함수 정의
인터페이스로 함수도 정의할 수 있다.
interface Add {
(num1:number, num2: number) : number
}
const add : Add = function(x, y) {
return x + y;
}
이를 사용하면
add(10, 20); // 정상
add(10, '20'); // 문자열로 넣으면 오류 발생
다음은 나이를 받아서 성인인지 여부를 리턴하는 함수를 만들어보자.
interface IsAdult {
(age:number):boolean;
}
const a:IsAdult = (age) => {
return age > 19;
}
a(33); // true
인터페이스로 클래스 정의
인터페이스로 클래스도 정의할 수 있다.
// Car 인터페이스를 정의하고
interface Car {
color: string;
wheels: number;
start(): void
}
// Car를 구현하는 클래스를 정의
class Bmw implements Car {
color;
wheels = 4;
constructor(c: string) {
this.color = c;
}
start() {
console.log('go...')
}
}
// Car 객체를 생성
const b = new Bmw('green');
console.log(b);
b.start(); // go...가 잘 출력된다.
인터페이스 확장
인터페이스는 확장이 가능하다.
interface Car {
color: string;
wheels: number;
start(): void
}
// Car를 확장
interface Benz extends Car {
door: number;
stop(): void;
}
const benz : Benz = {
door: 5,
stop() {
console.log('stop');
},
color: 'black',
wheels: 4,
start() {
console.log('go...')
}
}
참고로 확장은 여러 개를 할 수도 있다.
interface Car {
color: string;
wheels: number;
start(): void
}
interface Toy {
name: string;
}
// Car와 Toy를 모두 확장하는 경우에 사용
interface ToyCar extends Car, Toy {
price: number;
}