03-1. 타입스크립트 변수 선언문
1. 타입스크립트 기본 제공 타입
1) 자바스크립트 타입타입스크립트 타입
유형 | 자바스크립트 타입 | 타입스크립트 타입 |
수 타입 | Number | number |
불리언 타입 | Boolean | boolean |
문자열 타입 | String | string |
객체 타입 | Object | object |
2. let과 const 키워드
1) ES5 자바스크립트
: variable의 앞 세 글자를 딴 var라는 키워드를 사용해 변수를 선언
- 그러나, var는 다른 프로그래밍 언어와는 다르게 동작한다.
2) ESNext 자바스크립트
: let, const라는 키워드를 도입해 다른 프로그래밍 언어와 같은 방식으로 동작하게 했다.
- 사실상 ESNext는 var 키워드를 사용하지 말라고 권고한다.
3-1) let 선언
let 변수 이름 [= 초깃값]
// 예시
let age = 25;// 초기값 선언
age = 30;// 값 변경 가능
- let으로 선언한 변수는 코드에서 그 값이 수시로 변경될 수 있음을 암시한다.
3-2) const 선언
const 변수이름 = 초깃값
// 예시
const birthYear = 1995; // 초기값 선언
// birthYear = 2000; // 오류 발생: const 변수는 재할당 불가
- const로 변수를 선언할 때는 반드시 초기값을 명시해야 한다.
- const으로 선언한 변수는 코드에서 변숫값이 절대 변하지 않는다는 것을 암시한다.
3. 타입 주석 (Type annotation)
: Javascript 변수 선언문을 확장해 타입을 명시할 수 있다.
1) 형태
let 변수이름 : 타입 [=초깃값]
const 변수이름 : 타입 = 초깃값
2) 예시
let n : number = 1
let b : boolean = true // 혹은 false
let s : string = 'hello'
let o : object = {}
3) 특징
- let으로 선언한 변숫값은 타입주석으로 명시한 타입에 해당하는 값으로만 변경할 수 있다.
- 위의 예시에서 boolean으로 선언한 b 변수에 'hello' 또는 1과 같은 다른 타입의 값으로 변경할 수 없다. (변경 시, 타입 불일치 오류 발생)
4. 타입 추론 (type inference)
: Typescript는 Javascript와 호환성을 위해 타입 주석 부분을 생략할 수 있다.
- 타입스크립트 컴파일러는 대입 연산자 = 오른쪽 값(초깃값)에 따라 변수의 타입을 지정한다.
- 이후에 각 변수에는 해당 타입의 값만 저장할 수 있다.
1) 예시
let n = 1// n의 타입을 number로 판단
let b = true// b의 타입을 boolean으로 판단
let s = 'hello'// s의 타입을 string으로 판단
let o = {}// o의 타입을 object로 판단
5. any 타입
: Typescript는 Javascript와 호환을 위해 any라는 이름의 타입을 제공한다.
- 값의 타입과 무관하게 어떤 종류의 값도 저장할 수 있다.
1) 예시
let a : any = 0
a = 'hello'
a = true
a = {}
6. undefined 타입
: Javascript에서 undefined는 값이지만, Typescript에서는 타입이면서 값이기도 한다.
1) 타입의 상속관계
- any는 모든 타입의 루트 타입, 즉 최상위 타입
- undefined는 모든 타입의 취하위 타입
2) 타입스크립트의 타입 계층도

7. 템플릿 문자열
: 변수에 담긴 값을 조합해 문자열을 만들 수 있게 해준다.
- 이 구문은 역따옴표(backtick)으로 문자열을 감싸고, 변수를 ${]기호로 감싸는 형태로 만들 수 있다.
1) 형태
`${변수 이름}`
2) 예시
let count = 10, message = 'Your count'
let result = `${message} is ${count}`
console.log(result)
03-2. 객체와 인터페이스
0. 개요
: object 타입은 인터페이스와 클래스의 상위 타입이다.
1) 예시
let o : object = {name : 'jack', age: 32}
- object 타입으로 선언된 변수는 number, boolean, string 타입의 값을 가질 수는 없지만, 속성 이름이 다른 객체를 모두 자유롭게 담을 수 있다.
- object 타입은 마치 객체를 대상으로 하는 any 타입처럼 동작한다.
2) 인터페이스의 고안 이유
o = {first : 1, second : 2};
: 타입스크립트의 인터페이스 구문은 앞의 경우처럼 동작하지 않게 하려는 목적으로 고안되었다.
- 즉, 인터페이스를 사용하면, 변수 o에는 항상 name과 age 속성으로 구성된 객체만 가질 수 있기에 오류가 발생한다.
1. 인터페이스 선언문
: 인터페이스의 목적은 객체의 타입을 정의하는 것이다.
- interface라는 키워드를 사용해 선언한다.
- 객체를 의미하는 중괄호 {}로 속성의 이름과 타입을 나열하는 형태로 사용한다.
1) 형태
interface 인터페이스 이름 {
속성 이름[?] : 속성타입[, ... ]
}
2) 예시
interface IPerson {
name : string
age : number
}
3) 오류 예시
: 인터페이스의 조건을 벗어나는 경우 오류가 발생한다.
interface IPerson {
name : string
age : number
}
// 정상
let good : IPerson = {name : 'Jack', age : 32}
// 오류
let bad1 : IPerson = {name : 'Jack'}// age 속성이 없으므로 오류
let bad2 : IPerson = {age : 32}// name 속성이 없으므로 오류
let bad3 : IPerson = {}// name과 age 속성이 없으므로 오류
let bad4 : IPerson = {name : 'Jack', age : 32, etc : true}// etc 속성이 있어서 오류
2. 선택 속성 구문
: 인터페이스를 설계할 때, 어떤 속성은 반드시 있어야 하지만, 어떤 속성은 있어도 되고 없어도 되는 형태로 만들고 싶을 수 있다. 이러한 속성을 선택 속성(optional property)라고 한다.
- 속성 이름 뒤에 물음표 기호를 붙여서 만든다.
1) 예시
interface IPerson2 {
name : string
age : number
etc? : boolean
}
// 정상
let good1 : IPerson2 = {name : 'Jack', age : 32}
let good2 : IPerson2 = {name : 'Jack', age : 32, etc : true}
3. 익명 인터페이스
: interface 키워드를 사용하지 않고, 인터페이스의 이름도 없는 인터페이스를 만들 수 있다.
1) 형태
let ai : {
name : string
age : number
etc? : boolean
} = {name : 'Jack', age : 32}
2) 함수로 구현한 예시
function printMe(me : {name : string, age : number, etc? : boolean}) {
console.log(
me.etc
? `${me.name} ${me.age} ${me.etc}`
: `${me.name} ${me.age}`
)
}
printMe(ai);
: me의 타입을 정의하기 위해 익명 인터페이스가 사용되었다.
03-3. 객체와 클래스
1. 클래스 선언문
: Typescript는 객체지향 언어에서 흔히 볼 수 있는 class, private, public, protected, implments, extend와 같은 키워드를 제공한다.
1) 형태
class 클래스 이름{
[private | protected | public] 속성이름[?] : 속성 타입[...]
}
2) 예시
class Person1{
name : string
// name : string = '' // 오류 방지
age?: number
}
- 이 경우 오류가 발생한다. 문자열의 경우 초기값이 세팅되어야 하는듯 하다.
3) 사용 방법
let jack1 : Person1 : new Person1()
jack1.name = 'Jack';
jack2.age = 32
console.log(jack1) // Person1 {name : 'Jack', age : 32}
2. 접근 제한자
: 클래스의 속성은 public, private, protect와 같은 접근 제한자(access modifier)를 이름 앞에 붙일 수 있다.
- 만일 생략하면, 모두 public으로 간주한다.
3. 생성자
: 클래스의 인스턴스가 생성될 때 호출되는 특별한 메서드로, 주로 속성을 초기화하는 데 사용된다.
1) 예시
export class Person2{
constructor(public name: string, public age? : number) { }
}
let jack2: Person2 = new Person2('Jack2', 33);
console.log("jack2 : ", jack2);// Person1 {name : 'Jack2', age : 33}
- 생성자의 매개변수에 public와 같은 접근 제한자를 붙이면, 해당 매개변수의 이름이 가진 속성이 클래스에 선언된 것처럼 동작한다.
2) 함축되지 않은 예시
export class Person3 {
name: string;
age?: number
constructor(name: string, age?: number) {
this.name = name;
this.age = age;
}
}
let jack3: Person3 = new Person3('Jack3', 34)
console.log("jack3 : ", jack3);// Person3 {name : 'Jack3', age : 34}
4. 인터페이스 구현
1) 형태
class 클래스이름 implements 인터페이스이름 {
...
}
- 인터페이스는 이러이러한 속성이 있어야 한다는 규약(spec)에 불과할 뿐, 물리적으로 해당 속성을 만들지 않는다.
- 따라서 클래스 몸통에는 반드시 인터페이스가 정의하고 있는 속성을 멤버 속성으로 포함해야 한다.
2) 예시
// 인터페이스로 클래스 선언
interface IPerson4{
name: string;
age?: number;
}
export class Person4 implements IPerson4{
constructor(public name: string, public age? : number) { }
}
let jack4: Person4 = new Person4('Jack4', 35);
console.log('jack4 : ', jack4);// Person4 {name : 'Jack4', age : 35}
5. 추상 클래스
: abstract 키워드를 class 키워드 앞에 사용해 추상 클래스를 만들 수 있다.
- 추상클래스는 자신의 속성이나 메소드 앞에 abstract를 붙여, 나를 상속하는 다른 클래스에서 이 속성이나 메서드를 구현하게 한다.
1) 형태
abstarct class 클래스이름{
abstract 속성이름 : 속성타입
abstarct 메소드이름 () {}
}
2) 예시
// 추상 클래스 선언
abstract class AbstractPerson5 {
// 추상 속성 name: 서브 클래스에서 반드시 구현해야 하는 속성
abstract name: string;
// 생성자: age 속성을 초기화할 수 있는 생성자
constructor(public age?: number) { }
}
6. 클래스의 상속
: 부모 클래스를 상속 받는 상속 클래스를 만들 수 있다.
- extends 키워드를 사용해 상속 클래스를 만든다.
1) 형태
class 상속클래스 extends 부모클래스{
...
}
2) 예시
// AbstractPerson5를 상속하는 Person5 클래스
export class Person5 extends AbstractPerson5 {
// 생성자: name 속성을 초기화하고, 부모 클래스의 생성자를 호출
constructor(public name: string, age?: number) {
super(age);// 부모 클래스의 생성자 호출
}
}
let jack5: Person5 = new Person5('Jack5', 36);
console.log('jack5 : ', jack5);
- Person5 클래스는 추상 클래스를 상속해, AbstractPerson5가 구현한 age를 얻고, 그 다음에 AbstarctPerson5를 상속받는 클래스가 구현해야 할 name 속성을 구현한다.
- 부모 클래스의 생성자를 super 키워드로 호출할 수 있다.
7. static 속성
: 타입스크립트 클래스는 정적인 속성을 가질 수 있다.
1) 형태
class 클래스이름{
static 정적_속성_이름 : 속성_타입
}
2) 예시
export class A {
testValue: number = 0;
static initValue = 1
public increase(): void {
A.initValue++;
}
public increase2(): void {
this.testValue++;
}
}
export let initVal = A.initValue;
console.log("static : ", initVal);
공부 후기
- JS와 TS의 타입 차이 : 자바스크립트 타입과 타입스크립트 타입의 선언 키워드가 대소문자가 다른 키워드로 되어 있다는 점을 새로 알게 되었다. 나는 TS를 나중에 배웠으므로, 대문자보다 작은 소문자로 생각하면서 구분해봐야겠다.
- var 키워드 : ESNext는 var 키워드를 사용하지 말라고 권고한 점에 대해서 새로 알게 되었다. 변수를 선언할 때 주로 let, const를 많이 사용하긴 했지만, 그래도 JS를 수업에서 처음 배울 때 var를 많이 사용했던 기억이 나서 신기했다.
- 타입 주석 : TS의 특징이 바로 이름처럼 타입이 지정되는 점인데, 타입 주석이라는 점도 새로 알게 되었고, 이 부분이 중요한 점이라는 것도 깨닫게 되었다.
- undefined : undefined가 TS에서는 타입도 되고, 값도 된다는 점을 새로 알게 되었다. 이를 잘 참고해서 사용하면 유용할 것 같았다.
- 인터페이스 필수 사용 | 선택 속성 : 인터페이스에 선언한 변수들을 무조건 사용해야 한다는 점을 새로 알게 되었다. 사용하고 싶은 속성만 있을 경우도 존재할 수 있는데, 이럴 때에는 ?를 사용해서 선택 속성으로 선언하면 된다고 해서 신기했다. 확실히 TS는 JS에 비해 타입에 있어서 엄격한듯 하다.
- 익명 인터페이스 : 익명 인터페이스라는 것을 제대로 안 게 이번이 처음인듯 하다. 익명 인터페이스는 객체를 생성할 때마다 필요한 속성을 간단하게 정의할 수 있게 해주며, 별도의 인터페이스를 만들 필요 없이 코드가 간결해진다는 점도 알게 되었다.
- 생성자의 매개변수 : 생성자의 매개변수에 public와 같은 접근 제한자를 붙이면, 해당 매개변수의 이름이 가진 속성이 클래스에 선언된 것처럼 동작한다는 것을 새로 알게 되었다. 이를 통해 보다 코드를 간결하게 작성할 수 있어서 신기했다.
- 추상 클래스 : 추상 클래스를 이해하는 데 시간이 좀 걸렸다. 추상 메서드는 추상 클래스를 상속하는 다른 클래스에서 반드시 구현해야 한다는 점과 이로 인해 서브 클래스는 추상 메서드를 자신의 방식으로 구체적으로 정의해야 한다는 점을 새로 알게 되었다. 마치 서브 클래스에서 부모 클래스의 메서드를 재정의하는 개념인 override처럼 느껴졌다.
- static 키워드 : 정적 키워드에 대해서 아직은 이해도가 조금 부족한듯 하다. 검색해보니, "모든 인스턴스에서 공유되며, 클래스 이름으로 직접 접근할 수 있다. 정적 속성은 주로 클래스 수준에서 유지해야 할 데이터나 메서드를 정의할 때 사용된다." 라고 하는데, 조금 더 이해가 필요할 것 같다.
'💻 개발 > 📘 TypeScript' 카테고리의 다른 글
3. 객체와 타입 (2) (1) | 2025.02.12 |
---|---|
2. 타입스크립트 프로젝트 생성과 관리 (0) | 2025.02.12 |
1. 타입스크립트와 개발 환경 만들기 (0) | 2025.02.12 |