변수 선언
var 선언자의 특징
- 호이스팅
- 블록 레벨 스코프가 지원되지 않음(함수 레벨 스코프)
- 호이스팅
변수가 선언된 위치에 관계없이 스코프 최상위로 끌어올림되어 같은 스코프라면 어디서든 호출 할 수 있는 것
1 | helloMessage = "hello"; |
변수를 먼저 선언하고 할당한 것처럼 변수 선언을 호이스팅에서 처리함
- 함수 레벨 스코프
함수 내에서만 유효하고 함수 외부에서는 참조할 수 없음
1 | var myName = "sad"; |
즉, var은 블록레벨 스코프를 지원하지 않는다.
- 블록 레벨 스코프
블록{} 내에서만 유효하고 블록 외부에서는 참조할 수 없음
1 | // 블록 레벨 스코프를 지원하지 않을 경우 |
블록 레벨 스코프에 대표적 선언
let, const
클래스, 인터페이스, 타입 에일리어스, enum 선언
let 선언자 특징
- 같은 블록 내에서 같은 이름의 변수를 중복해서 선언 불가
- 변수를 초기화하기 전에는 변수에 접근할 수가 없으므로 호이스팅 방지
- 선언할 변수에 블록 레벨 스코프 적용
- let선언자로 선언된 변수는 같은 블록 내에서 중복 선언 할 수 없다.
1 | let myName2; |
- 호이스팅 방지
1 | console.log(myName); //Uncaught ReferenceError: myName is not defined |
변수를 초기화 하기전에는 변수에 접근 불가
- 블록 레벨 스코프 지원
1 | let myName2 = "sad"; |
실습 폴더와 파일 구성
1 | { |
상수 선언
const는 선언 할 때 초기화는 가능하지만 재할당은 불가능한 읽기 전용 (read only) 변수가 된다. 블록 레벨 스코프이며 호이스팅이 되지 않는다.
1 | // const로 선언했으므로 상수가 된다. |
특히 타입 어노테이션 (:)을 추가하지 않더라도 할당한 값에 따라 타입이 추론되어 number 타입이 된다.
const는 블록 레벨 스코프이다.
const는 입력값의 타입에 상관없이 변수를 읽기 전용으로 만든다.
변수가 읽기 전용이 되면 값을 새로 할당할 수 없다.
1 | const profile = { |
- 그러나 예외적으로 const로 선언한 변수라도 객체 리터럴의 속성으로는 변경이 가능하다.
1 | const profile = { |
이는, 타입스크립트가 값 자체를 재할당할 수는 없지만, 속성값의 변경은 허용하는 특성을 갖고 있기 때문이다.
타입 검사와 타입 선언
점진적 타입 검사
타입 검사는 정적 타입 검사(statically type checking)과 동적 타입 검사(dynamically type checking)으로 나뉨
정적 타입 검사 : 자바, C++
동적 타입 검사 : 자바스크립트
한편, 타입스크립트는 점진적 타입 검사(gradually type checking)을 수행 , 필요에 따라 타입 선언 생략을 허용한다.
타입을 생략하면 암시적 형변환이 일어난다.
1 | function add10(a) { |
매개변수 a에 타입을 선언하진 않았지만, 타입스크립트 컴파일러가 a를 오류로 취급하지 않는다.
또한 변환된 자바스크립트는 동적으로 타입이 결정되어 오류 없이 실행된다.
필요에 따라 타입을 생략할 수도 , 점진적으로 추가할 수도 있다.
대표적으로 any타입은 모든 타입의 최상위 타입으로 동적 타입과 정적 타입의 경계에 있으며 어떤 타입의 변수도 받아들인다.(심지어 타입이 없는 변수도 받아들임)
자바스크립트의 동적 타이핑
자바스크립트는 기본 타입과 객체 타입이 있다.
- 기본 타입 - Number, String, Boolean
- 객체 타입 - 객체 리터럴, 배열, 내장 객체
자바스크립트에도 타입이 있지만 타입을 강제할 수는 없고 값 할당시에 타입을 추론한다.
1 | var number = 10; // number 타입 |
이처럼 값을 변수에 할당할 때 타입이 정해지는 것을 동적 타이핑이라고 한다.
타입스크립트에서도 타입을 선언하지 않으면 입력값에 따라 타입이 결정된다. 정해진 타입을 예측할수 없으므로 타입을 검사하는 코드가 추가로 필요해지고, 이는 성능상으로 좋지 않다.
1 | var width = 10; |
타입 계층도
가장 상위에 any가 있고 그 아래에
- 기본타입
- 객체 타입
- 기타 타입(유니언 타입, 인터섹션 타입)

기본 타입
기본 타입(primative types)는 보편적으로 많이 사용된다.- string, number, boolean
- symbol(es6에서 추가됨)
- enum
- 문자열 리터럴
- string 타입은 작은 따음표나 큰 따음표, 역따옴표(백틱 , backtick)을 이용할 수 있다.
- number 타입은 es6에서 10진수뿐만 아닌 16진수, 2진수,8진수도 지원한다.
- bolean 타입은 true 또는 false 값 할당할 수 있다.\
- symbol 은 Symbol() 함수를 이용해 생성한 고유고 수정 불가능한 데이터 타입이다.
1 | let hello = Symbol(); |
- enum 은 number에서 확장된 타입으로 enumm의 첫번째 요소에는 숫자 0의 값이 할당된다. 그 다음부턴 1씩 증가한다.
1 | // 타입스크립트 |
- 문자열 리터럴 타입은 string 타입의 확장 타입으로 사용자 정의 타입에 정의한 문자열만 할당받을수 있다.
객체 타입
객체 타입은 속성을 포함한다.- Array
- Tuple
- Function
- 생성자
- Class
- Interface
- array는 배열 요소에 대응하는 타입이다.
1 | let items: number[] = [1, 2, 3]; |
- tuple은 배열 요소가 n개로 정해질 때 각 요소별로 타입을 지정한다.
1 | // 배열 요소가 문자열과 숫자일 때 |
- 함수타입
- class 타입과 interface 타입은 객체 타입(object types)로 본류된다.
- 기타 타입
- 유니언(union)
- 인터섹션(intersection)
- 특수 타입
- 유니언 타입은 2개 이상의 타입을 하나의 타입으로 정의한 타입이다.
1 | var x: string | number; |
- 인터섹션 타입은 두 타입을 합쳐 하나로 만들 수 있는 타입이다.
1 | interface Cat { |
위 코드에서 birdCat 변수가 인터섹션 타입인 Cat&Bird로 선언되어 있으므로 할당 객체는 leg와 wing 만 허용한다.
- void , null, undefined는 타입 계층도 가장 아래층에 위치한다.
- void는 빈 값을 나타내는 타입이다. 함수에 리턴값이 없을떄 void 타입을 선언할 수 있는데 undefined나 null값을 받을 때 사용한다.
- null 과 undefined는 다른 모든 타입의 하위 타입(subtype)이다.
- undefined는 빈 값으로도 초기화되지 않는 타입이다.
- null 타입은 빈 객체로 초기화된다.
타입스크립트의 타입 계층도는 기존 자바스크립트 타입을 확장한 형태이다. 자바스크립트 타입과 비교했을 때 다음과 같은 타입이 추가되었다.
- 객체 타입의 상위 타입으로 any추가
- any 타입의 특수 타입으로 유니언 타입과 인터섹션 타입 추가
- 객체 타입의 하위 타입으로 Array,Interface,Tuple추가
- void 타입 추가
변수에 타입 지정
타입 스크립트는 강력한 타입을 지원한다.
1 | var <변수식별자> : <타입> = <값>; |
자바스크립트의 타입
타입스크립트에서는 자바스크립트에서 지원하는 내장타입을 제공한다.
크게 기본타입, 객체타입, 함수타입 이 있다.
내장 타입
boolean, string, number 등이 있다. 이들은 명시적으로 전역 객체를 통해 직접 생성 가능하다.
1 | var type1 = new Boolean(false); |
Symbol() 함수처럼 객체 속성에 유일한 식별자로 사용하는 타입
null,undefined 처럼 null값이거나 아직 할당되지 않았다는 의미로 쓰이는 타입
이 외에도 object 타입 (배열이나 객체 리터럴 대상)
함수는 그 자체로 function 타입 등이 있다.
자바스크립트에서는 타입을 지정할 때 런타임 시 할당과 동시에 동적으로 타입이 결정되는 느슨한 타입
타입스크립트는 지정한 값만 받는 엄격한 타입 쳬계를 사용한다.
symbol 타입
자바스크립트 내장 타입중 symbol 타입은 es6에서 추가된 특징이다.
1 | let hello = Symbol("hello"); |
symbol 타입은 심벌 객체를 반환한다. “hello”인수는 심벌의 설명(description)을 의미한다. 심벌에 접근할 때 사용할 수 있으며 생략 가능하다.
만약, 어떤 변수를 불변 상수로 선언하려면 const를 사용한다.
1 | const hello = Symbol(); |
위와 같이 선언하면 hello는 유일하면서(Symbol() 함수 사용) 불면(const 사용)인 특성을 갖게된다.
symbol함수는 es6로 컴파일해야한다. tsconfig.json의 target을 es6로 선언하거나
1 | tsc sysmbol.ts(컴파일하려는 ts명) -t es6 |
명령어로 컴파일한다.
1 | let hello1 = Symbol("hello"); |
심벌 객체는 유일하므로 hello1과 hello2는 서로 다른 객체이다.
- Symbol() 함수의 반환값은 별다른 값을 취하지 않아도 그 자체로 식별자가 된다.
- Symbol()함수로 초기화된 변수는 객체 속성에 대한 유일한 식별자로서 값을 할당하는 용도로 사용한다.
enum 타입
enum 타입은 es6에서 제안된 타입으로 컴파일 시간에 평가되며, 타입 계층도에 따르면 number 타입의 하위타입으로 , 컴파일 후에는 객체 타입이 된다.
명명된 숫자 상수의 집합을 정의할때 사용한다.
enum 타입은 숫자 상수를 기억하기 좋은 키워드로 변환해서 사용가능하다.
1 | enum Day {속성 : 값, 속성 : 값} |
- 각 속성은 상수와 연결되며 첫 번째 속성의 인덱스는 0부터 시작한다. 또한 특별히 명시하지 않는 이상 순차적으로 1씩 증가한다. 초기값을 할당할 수도 있는데 기본적으로 숫자 할당이 가능하다.
- enum은 const를 붙여서 상수 enum으로도 선언할 수 있다. 이때 상수 enum은 읽기 전용이 된다.
1 | const enum WeekDay { |
이렇게 읽기 전용으로 설정하면 인덱스 접근 표현식에 문자열 리터럴만 허용한다.
1 | let day = WeekDay["Mon"]; // 문자열 리터럴 허용 가능 |
- 문자열 enum이 추가되어 초기값으로 문자열 할당 가능하다.
문자열로 초기값을 설정하면 연산식 할당은 할 수 없다.
1 | enum WeekDay3 { |
// TODO enum 타입 정리
타입스크립트의 내장타입
타입스크립트에서만 지원되는 내장타입을 알아본다.
any 타입
any 타입은 어떤 타입의 값도 받아들일수 있으며 최소한의 타입 검사만 수행한다.
1 | let basket: any = 10; |
- any는 모든 타입의 가장 최상위 타입이므로 자바스크립트의 모든 값을 할당 받을수 있다.
- any 타입을 선언하면 명시적으로 타입을 선언한거고, any 타입을 생략하면 타입이 없는 것
1 | let a; // let a : any;와 같음 |
- any 타입으로 선언된 변수는 최소한의 정적 타입 검사만 수행한다.
1 | let number = 50; |
선언되지 않은 어떤 메서드를 호출할 때 타입을 선언하지 않으면 오류를 발생시킴
object 타입
object 타입은 any와 비슷하게 타입 구분없이 값을 할당할 수 있지만 차이점이 있다.
any 타입은 런타임시 속성의 유뮤를 검사한다.
object 타입은 컴파일 시간에 속성의 유무를 검사한다.
따라서, object 타입에 변수에 숫자를 할당해도 컴파일 시에 숫자 메서드를 인식하지 못하므로 컴파일 에러를 발생시킨다.
1 | let number2: any = 40; |
nolmplicaitAny 옵션
any 타입을 반드시 지정해야 할 때
1 | // tsconfig.json |
배열 타입과 제네릭 배열 타입
배열은 배열타입과 제네릭 배열 타입으로 나뉜다.
- 배열 타입
요소 타입에 []를 붙여서 선언한다. string,number,boolean, class, interface 모두 가능하다.
1 | let myVar: number[] = [1, 2, 3, 4, 5]; |
any[]타입으로 지정하면 어떤 요소든 배열에 추가 가능하다. 타입을 제약하고 싶을때는 유니언 타입을 이용해 선언한다.
(유니언타입 : 2개 이상의 타입을 하나의 타입으로 정의)
1 | let myVar: number | string | boolean = [1, "1", true]; |
- 제네릭 배열
Array[T] 형태로 선언한다. T는 타입을 의미한다.
1 | let myVar: Array<number> = [1, 2, 3]; |
마찬가지로 유니언 타입으로 배열의 타입을 제약 가능하다.
1 | let myVar: Array<number | string | boolean> = [1, "1", true]; |
내장 타입 외에 객체 타입도 받을 수 있다.
1 | let nums: Array<() => string> = [() => "one", () => "two"]; |
배열타입이건 제네릭 배열 타입이건 javascript로 컴파일 시에는 타입이 제거되므로 동일한 결과를 가져옴
튜플 타입(tuple type)
배열 요소에 대응하는 n개에 대한 타입이다.
1 | //배열 : 요소 개수에 제한이 없다. |
타입스크립트 2.7 이후 튜플 타입에 따라 할당된 배열의 요소 수가 고정되었다.
void, null,undefined
void는 함수의 반환 값이 없을 때 지정하는 타입으로 null, undefined만 할당 할 수 있다.
void는 null, undefined의 상위 타입이다.
반환값이 없을 때 이를 명시적으로 나타내기 위헤 void를 지정한다.
1 | function hello(): void { |
hello() 의 반환 타입은 void 지만 리턴값이 없으므로 undefined로 할당된다.
void 타입은 undefined나 null만 할당할 수 있으므로 유용한 타입이 아니다.
null vs undefined
undefined는 undefined 타입이며 아직 초기화 되지 않았음을 의미한다.
null은 값이기 때문에 null을 할당하고 나면 object 타입이 된다.
undefined와 null 모두 값이 없다는 점에서는 같다. 다만 undefined는 선언은 했으나 값이 할당되지 않는 경우이고,
null은 값을 할당했으나 그 값이 없는 경우이다.
1 | var testUndefined; |
값이 없음을 나타내기 위해서 null을 할당하는것인 권장하지 않는다.
1 | let empty; // undefined |