타입스크립트 - 변수 선언과 기본 타입

var 의 특징

  • 호이스팅
  • 함수 레벨 스코프(블록 레벨 스코프 지원 되지 않음)

var의 첫 번째 특징은 호이스팅 입니다. 호이스팅은 선언한 변수가 스코프의 최상위로 끌어올림 되는 현상입니다.
두 번째 특징은 함수 레벨 스코프(function level scope)를 지원하므로 함수 내에서 선언한 변수는 함수 내에서만 유효하고 함수 외부에서는 참조할 수 없다는 것이다. var 는 블록 레벨 스코프(block level scope)를 지원하지 않는다. 블록 레벨 스코프란 블록{} 내에서만 유효하고 블록 외부에서는 참조 할 수 없는 것을 말한다.

블록 레벨 스코프를 지원하는 하는 대표적인 선언은 다음과 같다.

  • let, const
  • 클래스, 인터페이스, 타입 에일리어스(type alias), enum 선언

let 의 특징

호이스팅 방지와 블록 레벨 스코프를 지원할 방법으로 ES6에서 let 선언자가 나왔고, 타입스크립트에서도 let 선언자를 지원합니다. 다음과 같은 특징을 가지고 있습니다.

  • 블록 내에서 변수를 중복 선언 방지
  • 호이스팅 방지
  • 선언할 변수에 블록 레벨 스코프 적용

const 의 특징

const는 ES6의 특징이며 타입스크립트에서도 지원한다. let과 같은 블록 레벨 스코프를 지원하며 호이스팅을 일으키지 않습니다.
let과 다른 점은 const는 변수를 상수로 선언할 때 사용한다는 점이다. const를 이용해 변수를 상수로 선언하면 선언할 때 초기화는 가능하지만 재할당되지 않는 읽기전용(read only) 변수가 됩니다.
예외적으로 const로 선언한 변수라도 객체 리터럴의 속성으로는 변경할 수 있습니다.

1
2
3
4
5
6
const profile = {
name : "happy",
month: 8,
}
// const profile = "unhappy"; 재할당 불가능
profile.name = "happy2"; // 속성에 할당 가능

이는 타입스크립트가 값 자체를 재할당하는 것은 허용하지 않지만, 속성값의 변경을 허용하는 특성이 있기 때문이다.

타입 검사와 타입선언

타입 검사의 종류

언어에 따라 수행하는 타입 검사의 종류는 크게 ‘정적 타입 검사(statically type checking)’와 ‘동적 타입 검사(dynamically type checking)’로 나뉩니다. 정적 타입 검사는 자바, C++ 등의 언어에서 사용하고, 동적 타입 검사는 실행시간에 타입검사를 수행하며 대표적으로는 자바스크립트가 있습니다.

타입스크립트는 ‘점진적 타입 검사(gradually type checking)’를 수행합니다. 점진적 검사를 하는 대표적인 언어로는 타입스크립트와 파이썬등이 있습니다. 점진적 타입 검사는 컴파일 시간에 타입 검사를 수행하면서 필요에 따라 타입 선언의 생략을 허용합니다. 타입스크립트에서 점진적 타이핑을 성명할 때 적절한 타입으로 any가 있습니다.
any 타입은 모든 타입의 최상위 타입이며, 동적 타입과 정적 타입의 경계선에 있는 타입으로 타입스크립트에서는 특별히 다뤄집니다.
any 타입으로 선언된 변수는 어떤 타입의 변수도 받아들이면서 심지어 타입이 없는 변수도 받아들입니다.

자바스크립트의 동적 타이핑

자바스크립트에는 기본타입과 객체타입이 있습니다. 기본 타입은 Number, Boolean, String 과 같은 타입을 말하고, 객체 타입으로는 객체 리터럴, 배열, 내장객체가 있습니다.
자바스크립트에는 타입이 있지만 타입을 강제할 수는 없고 값을 할당할 때 타입이 추론됩니다. 값을 변수에 할당 할때 타입이 정해지는 것을 동적 타이핑(dynamic typing)이라 합니다.

타입을 명시하지 않고 값을 할당하면 입력값에 따라 타입이 동적으로 정해지므로 정해진 타입을 예측할 수 없습니다. 따라서 변수의 안전한 사용을 위해서는 타입을 검사하는 코드를 불가피하게 추가 해야 합나다.

타입 스크립트 계층도

타입스크립트 타입계층도

기본 타입

기본 타입은 보편적으로 많이 사용되는 내장 타입으로서 타입 스크립트에서 지원하는 기본 타입의 종류는 다음과 같습니다.

  • String, number, boolean
  • symbol(ECMA 2015에 추가)
  • enum
  • 문자열 리터럴

문자열 값을 표현할 때 역따옴표를 이용할수 있는데 역따옴표를 이용하면 줄 구분 없이 문장을 입력할 수 있습니다. 또한, 역따옴표 내에는 내장 표현식을 이용할 수 있습니다.

객체 타입

객체 타입은 속성을 포함하고 있으며, 호출 시그니처, 생성자 시그니처 등으로 구성된 타입입니다. 타입스크립트에서 지원하는 객체 타입의 종류는 다음과 같습니다.

  • Array
  • Tuple
  • Function
  • Constructor
  • Class
  • Interface

tuple은 배열 요소가 n개로 정해질 때 각 요소별로 타입을 지정한 타입입니다. 예를 들어 배열 요소가 문자열과 숫자라면 [string, number] 같은 형태로 타입을 정의합니다.

기타 타입

  • 유니언(Union)
  • 인터섹션(Intersection)
  • 특수 타입

유니언 타입은 2개 이상의 타입을 하나의 타입으로 정의한 타입입니다. 특수 타입으로 타입 계층도의 가장 아래쪽에 위치한 void, null, undefined 있습니다. void는 빈 값을 나타내는 타입입니다.
함수에 반환값이 없을 때 void 타입을 선언할 수 있는데 undefined 나 null 값을 받을 때 사용합니다.

non-nullable은 null이나 undefined를 허용하지 않는 타입이고, 룩업(lookup) 타입은 인터페이스를 이용해 키값을 설정할 수 있는 타입입니다.

  • 객체 타입의 상위 타입으로 any 추가
  • any 타입의 특수 타입으로 유니언 타입과 인터섹션 타입추가
  • 객체 타임의 하위 타입으로 Array, Interface, Tuple 추가
  • Void 타입 추가

변수에 타입 지정

[형식]
var <변수 식별자>:<타입> = <값>;

변수에 타입을 명시적으로 지정할 수 있습니다. 명시적 타입표기를 하면 변수에 어떤 값이 할당될지 직관적으로 알 수 있습니다.

자바스크립트의 타입

타입을 지정할 수 있는 타입스크립트와 달리 자바스크립트에서는 별도로 타입을 지정하는 절차가 없고, 런타임 시 변수에 값이 할당되면 동적으로 타입이 결정됩니다.

symbol 타입

ES6에서 추가된 특징으로 객체 속성의 유일하고 불변적인 식별자로 사용된다. Symbol 타입은 Symbol 함수를 이용해 다음과 같은 형태로 선언한다.

1
let hello = Symbol("hello");

Symbol 함수는 심벌 객체를 반환, 이때 Symbol 함수가 유일한 식별자를 생성하는 팩토리 함수의 역할을 합니다. Symbol 함수를 호출할 때 “hello” 인수는 심벌의 설명을 의미한다.
설명은 심벌에 접근할 때 사용할 수 있으며, 생략할 수 있다.

enum 타입

enum 타입은 ES6에 제안된 타입으로, 컴파일 시간에 평가된다. 타입 계층도로 보면 number 타입의 하위 타입으로 자바스크립트로 컴파일된 후에는 객체 리터럴이나 배열처럼 객체 타입이 됩니다.
typeof를 통해 타입 이름을 표시하면 object로 표시됩니다.

enum은 명명된 숫자 상수의 집합을 정의할 때 사용합니다. 명명된 숫자 상수는 enum의 속성에 대응하는 값으로서 속성은 열거해 선언할 수 있습니다.

[형식]
enum Day { 속성: 값, 속성: 값, 속성: 값, … };

타입스크립트의 내장 타입

any 타입

any 타입은 제약이 없는 타입으로 어떤 타입의 값도 받아들일 수 있습니다. 자바스크립트가 최소한의 정적 타입 검사를 수행하는 것처럼 최소한의 타입 검사만 수행 합니다.
임의의 값을 받아들일 때 any 타입은 any 키워드로 선언할 수 있습니다.

1
2
3
var basket: any = 10;
basket = true;
basket = "banana";

any는 확정된 타입은 아니지만 어떤 값이든 할당받을 수 있습니다. 뿐만아니라 배열의 타입으로 사용하면 어떤 타입의 요소도 받아들일 수 있으므로 유연하게 활용할 수 있습니다.

any 타입은 모든 타입의 가장 최상위 타입입니다. 다시 말해 모든 타입은 any 타입의 하위 타입입니다. 그래서 any 타입은 자바스크립트의 모든 값을 할당 받을 수 있습니다.

object 타입은 any 타입처럼 타입 구분 없이 값을 할당할 수 있는 특성이 있어 any 타입과 비슷하지만 속성 유무를 검사하는 시점이 다릅니다.
any 타입으로 선언한 변수는 속성의 유무를 런타임 시에 검사하지만, object 타입으로 선언한 변수는 컴파일 시간에 속성의 유무를 검사합니다.
따라서 object 타입의 변수에 숫자를 할당하더라고 컴파일 시에 숫자 메서드를 인식하지 못하므로 컴파일 시간에 에러가 발생합니다.

noImplicitAny 옵션

any 타입의 사용을 강제할때 컴파일 옵션 중 noImplicitAny를 true 로 설정합니다.

tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noImplicitAny": true
}
}

noImplicitAny 옵션은 false 가 기본값이므로 noImplicitAny 옵션을 생략한다면 any 타입을 생략해도 괜찮습니다.

배열 타입과 제네릭 배열 타입

배열은 여러 개의 값을 하나의 변수에 담아 관리하는 자료구조이다. 여러 값을 모아 담기 때문에 컬렉션(collections) 이라 불리기도 합니다.
타입스크립트에서 배열 타입은 두 가지 형태로 나뉩니다.

  • 배열 타입 (array type)
  • 제네릭 배열 타입 (generic array type)

배열

배열 타입은 타입스크립트 0.9 버전 부터 지원 됐으며 다음 같이 선언합니다.

1
let myVar: number[] = [1, 2, 3, 4, 5];

배열 타입은 요소 타입에 []를 붙여 선언합니다. 요소 타입으로는 string, number, boolean 과 같은 내장 타입뿐 아니라 클래스나 인터페이스도 올 수 있습니다.
베열 요소의 타입이 정해져 있지 않다면 any 타입으로 지정할 수 있습니다.

1
let myVal: any[] = [1, "hi", true]

any 타입으로 지정하면 어떤 요소든 배열의 요소로 추가할 수 있습니다. 타입이 느슨하므로 타입을 제약하려면 유니언 타입을 이용해 선언합니다.

1
let myVal: (number | string | boolean)[] = [1, "hi", true]

제네릭 배열

제네릭 배열 타입은 타입스크립트 0.9 버전부터 지원됐으며 제네릭 배열 타입은 Array형태로 선언합니다. 이때 T 는 타입을 의미합니다.

1
let num:Array<number> = [1, 2, 3];

타입을 숫자나 문자열 타입으로 제약하려면 유니언 타입으로 선언

1
let num:Array<number | string> = [1, "hello"];

제네릭 타입 인수로 사용된 T는 컴파일 시점에 타입을 검사합니다. 타입스크립트에서 선언한 배열,제네릭 배열타입은 컴파일시 타입 검사를 위해 필요하고, 컴파일 후에는 타입이 제거된 배열만 남습니다.

튜플 타입

튜플 타입은 n 개의 요소로 이뤄진 배열에 대응하는 타입을 의미합니다. 튜플은 배열과 비슷한데, 배열은 배열 요소의 개수에 제한이 없고 string[]처럼 특정 타입으로 배열 요소의 타입을 강제할 수 있습니다.

1
2
let x: string[] = [ "tuple1",  "tuple2"];
let x: [string, number] = [ "tuple1", 100];

타입 스크립트2.7 이전에는 배열의 요소가 튜플타입에 선언된 개수를 초과하면 유니언 타입을 적용받았습니다. 그런데 2.7이 되면서 튜플 타입에 따라 할당 배열의 요소 수도 고정됐습니다.

void, null, undefined

void는 함수의 반환값이 없을 때 지정하는 타입입니다. void 타입에는 null이나 undefiend만 할당할 수 있습니다.
반환값이 없을 때 이를 명시적으로 나타내기 위해 void를 지정합니다.
null 이든 undefined 이든 불필요한 선언이 되거나 초기화하지 않았을 때 불안정한 연산을 초래할 수 있으므로 컴파일러 옵션에서 사용하지 못하게 막을 필요가 있습니다.

tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"strincNullChecks": true
}
}

그럼 기본적으로 변수에 할당되번 null 과 undefined는 더 이상 할당되지 못하고 컴파일 오류를 발생시킵니다.

Reference

타입스크립트 퀵스타트 - 루비페이퍼

댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×