TS LAB
TS 3.5 · 3부. 인터페이스와 제네릭

클래스와 접근 제한자

public · private · readonly 로 드러낼 것을 정합니다.

예상 학습 시간 16분 실행 단추가 있는 예제는 고쳐서 실행해 볼 수 있습니다 난이도 중급
개념 설명

클래스에도 타입을 적습니다

클래스는 JavaScript 문법입니다(JS 6.1). TypeScript 는 여기에 필드의 타입드러낼 것과 감출 것을 적게 합니다.

main.ts
class Product {
	name: string;
	price: number;

	constructor(name: string, price: number) {
		this.name = name;
		this.price = price;
	}

	label(): string {
		return `${this.name} ${this.price}원`;
	}
}

const p = new Product("연필", 1000);
console.log(p.label());
출력
연필 1000원

필드를 위에 미리 적어 두어야 합니다. JavaScript 에서는 this.name = name 만으로 만들어졌지만, TypeScript 는 어떤 필드가 있는지 알아야 하기 때문입니다.

상세 사용법

같은 것을 세 번 적지 않기

위 코드에서 name 이 세 번 나옵니다 — 필드 선언, 매개 변수, 대입. 생성자 매개 변수 앞에 접근 제한자를 붙이면 한 번으로 끝납니다.

main.ts
class Product {
	constructor(
		public name: string,
		private price: number,
		readonly code: string
	) {}

	label(): string {
		return `${this.name} ${this.price}원 (${this.code})`;
	}
}

const p = new Product("연필", 1000, "A-1");
console.log(p.label());
console.log(p.name);
출력
연필 1000원 (A-1) 연필

이것은 TypeScript 에만 있는 문법입니다. 바뀐 JavaScript 를 보면 this.name = name 이 들어가 있습니다 — 적어 주지 않은 것을 대신 만들어 준 것입니다.

상세 사용법

드러낼 것과 감출 것

제한자어디서 사용할 수 있나
public어디서나. 적지 않으면 이것입니다
private그 클래스 안에서만
protected그 클래스와 물려받은 클래스에서
readonly읽기만 됩니다. 위의 것들과 함께 붙일 수 있습니다
main.ts
class Product {
	constructor(public name: string, private price: number) {}
}

const p = new Product("연필", 1000);

console.log(p.price);
출력
7:15 TS2341 'price' 속성은 private이며 'Product' 클래스 내에서만 액세스할 수 있습니다.

이것은 검사할 때만 막습니다. 바뀐 JavaScript 에는 this.price 가 그냥 들어 있어 실행 중에는 읽을 수 있습니다. 실행할 때도 막으려면 JavaScript 의 # 를 사용합니다(JS 6.1).

상세 사용법

인터페이스를 지키게 하기

implements이 인터페이스를 갖추었다고 적어 두면, 빠뜨린 것을 클래스 쪽에서 잡아 줍니다.

main.ts
interface Printable {
	label(): string;
}

class Product implements Printable {
	constructor(public name: string) {}
}

const p = new Product("연필");
출력
5:7 TS2420 'Product' 클래스가 'Printable' 인터페이스를 잘못 구현합니다. 'label' 속성이 'Product' 형식에 없지만 'Printable' 형식에서 필수입니다.

extends물려받는 것이고 implements갖추었는지 확인만 하는 것입니다. 물려받을 것이 없으므로 내용은 직접 적어야 합니다.

흔한 실수

처음에 자주 걸리는 것

필드를 적지 않고 this 에 담는 것

생성자에서 this.total = 0 만 적으면 그런 속성이 없다고 막습니다. 위에 total: number; 를 적거나 매개 변수에 제한자를 붙입니다.

private 을 보안으로 여기는 것

검사할 때만 막습니다. 실행 중에는 그냥 속성이라 읽고 쓸 수 있습니다. 정말 감추려면 # 입니다.

implements 가 타입을 채워 주지 않습니다

implements 를 적어도 메서드의 매개 변수 타입은 직접 적어야 합니다. 확인만 할 뿐 물려주지 않습니다.

실습 문제

직접 해보기

1. 세는 클래스 난이도 중

숫자를 감춰 두고 더하기만 할 수 있는 클래스를 만드세요. 현재 값은 읽을 수 있어야 합니다.

class Counter {
	constructor(private count: number = 0) {}

	add(n: number = 1): void {
		this.count += n;
	}

	get value(): number {
		return this.count;
	}
}

const c = new Counter();
c.add();
c.add(5);

console.log(c.value);
2. 인터페이스 지키기 난이도 중

label(): string 을 요구하는 인터페이스를 만들고, 그것을 갖춘 클래스를 작성하세요.

interface Printable {
	label(): string;
}

class Product implements Printable {
	constructor(public name: string, private price: number) {}

	label(): string {
		return `${this.name} ${this.price}원`;
	}
}

console.log(new Product("연필", 1000).label());
요약

이 단원의 정리

  • 필드는 위에 미리 적어 두어야 합니다.
  • 생성자 매개 변수에 제한자를 붙이면 선언과 대입이 한 번에 됩니다.
  • private 는 검사할 때만 막습니다. 실행할 때 감추려면 # 입니다.
  • readonly 는 만든 뒤 바뀌지 않아야 할 것에 붙입니다.
  • implements 는 갖추었는지 확인만 하고 물려주지 않습니다.