TypeScript 변수 선언과 기본 타입

김대현·2020년 3월 15일
5

TypeScript 이론 정리

목록 보기
1/5
post-thumbnail

TypeScript 변수 선언과 기본 타입

1. 변수 선언

var

var 선언자는 기본적으로 Hoisting 의 원리를 따르고 있다. 변수가 선언된 위치와 관계없이 scope의 최상위로 끌어올림 되어 같은 스코프라면 어디서든 호출이 된다. 그러나 할당을 먼저하고 나중에 선언하는 코드는 가독성을 떨어뜨리므로 지양한다. 또한 function 레벨 스코프를 지원하므로 함수내에서 선언한 변수는 함수 내에서만 유효하다. 문제는 block 레벨 스코프를 지원하지 않는다.

//Function Level Scope
var mayName = "cool";

if(true) {
  var myName = "happy"
}
console.log(myName); // "happy"

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

  • let, cont
  • 클래스, 인터페이스, 타입 에일리어스, enum 선언

let

block 레벨 스코프를 지원하며 Hoisting을 방지한다. ES6의 대표적인 변수 선언에 사용된다.

//Block Level Scope
var mayName = "cool";

if(true) {
  let myName = "happy";
}
console.log(myName); // "cool"

const

let과 마찬가지로 block 레벨 스코프를 지원하며 Hoisting을 방지한다. ES6의 대표적인 상수 선언에 사용된다. 초기화는 되지만 재할당되지 않는 읽기 전용(readonly) 변수가 된다. 단 const로 선언한 변수라도 객체 리터럴의 속성으로는 변경할 수 있다.

const profile ={
 name: "nice",
 month: 9
}
const number = 5;

number = 4; // 할당 불가
profile.name = "cool1"; // 할당 가능
profile.month = 8; // 할당 가능

이는 타입스크립트가 속성값의 변경을 허용하는 특성이 있기 때문이다.

2. 타입 검사와 타입 선언

점진적 타입 검사

언어에 따라 수행하는 타입 검사의 종류

  • 정적 타입 검사 (statically type checking) : 실행 전에 타입 검사를 수행하며 Java, C++가 대표적이다.
  • 동적 타입 검사 (dynamically type checking) : 실행 중에 타입 검사를 수행하며 Javascript가 대표적이다. (loosely typed) 체계
  • 점진적 타입 검사 (gradually type checking) : 타입 검사를 수행하면서 필요에 따라 타입 선언의 생략을 허용한다. 타입 선언을 생략하면 암시적(implicit) 형변환이 일어난다. 타입스크립트에서 점진적 타이핑을 설명할 때 적절한 타입으로 any가 있다. any 타입은 모든 타입의 최상위 타입이며, any 타입으로 선언된 변수는 어떤 타입의 변수도 받아들이면서 심지어 타입이 없는 변수도 받아들인다. TypeScript, Python이 대표적이다. (strong typed) 체계

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

  • 기본 타입 (primitive types): Number, Boolean, String
  • 객체 타입 (object tpyes): 객체 리터럴, 배열, 내장 객체

    자바스크립트에는 타입이 추론된다. 이처럼 값을 변수에 할당할 때 타입이 정해지는 것을 동적 타이핑(dynamic typing)이라 한다.

var width = 10;
var myName = "happy";

console.log(typeof myName); //string
console.log(typeof width); //number
  • 자바스크립트에서는 해당 타입인것을 보장하기 위해 타입 검사 코드를 추가해야한다. (런타임에 비교 연산을 수행해야 하므로 성능에 지장을 줄 수 있다.)
  • 자바스크립트에서는 안전을 위해 해당 함수 인자가 어떤 타입인지 명시해주는 주석이 따로 필요하다.

기본 타입 (Primitive type)

기본타입은 보편적으로 많이 사용되는 내장 타입이다.

string, number, boolean, symbol, enum, 문자열 리터럴

Symbol type은 Symbol() 함수를 이용해 생성한 고유하고 수정 불가능한 데이터 타입으로 객체 속성의 식별자로 사용된다.

Symbol을 사용하는 이유 : 객체의 key가 문자열이나 정수일 때의 문제는, 프로그래머의 실수등으로 존재하는 객체의 key 값이 변경될 수 있다. Symbol로 정의할 경우 해당 키는 unique 하기에 중복되지 않는다.

let hello = Symbol("hello");
let hello2 = Symbol("hello");
console.log(hello === hello2); // false

const uniqueKey = Symbol();
let obj = {};

obj[uniqueKey] = 1234;
console.log(obj[uniqueKey]); //1234
console.log(obj); // { [Symbol()]: 1234 }

enum은 number에서 확장된 타입으로 첫 번째 Enum 요소에는 숫자 0 값이 할당된다. (ts 2.4부터는 문자열도 가능) 그 다음 값은 특별히 초기화되지 않는 이상 1씩 증가한다.

enum WeekDay = { Mon, Tue, Wed, Thu }
let day: WeekDay = WeekDay.Mon;

enum을 사용하는 이유 : 코드가 단순해지며 가독성이 좋다. 키워드 enum을 사용하기 때문에 구현의 의도가 열거임을 분명하게 나타낸다.

문자열 리터럴 타입은 string 타입의 확장 타입으로 사용자 정의 타입에 정의한 문자열만 할당받을 수 있다.

type EventType = "keyup" | "mouseover";

객체 타입 (Object type)

객체 타입은 속성을 포함하고 있으며, 호출 시그니처(call signature), 생성자 시그니처(const signature) 등으로 구성된 타입이다.

Array, Tuple, Function, 생성자, Class, Interface

  1. array는 배열 요소에 대응하는 타입이다.
let items: number[] = [1,2,3];
  1. tuple은 배열 요소가 n개로 정해질 때 각 요소별로 타입을 지정한 타입이다.
let tuple: [string, number];
tuple = ['hello', 10]; // OK
tuple = [10, 'hello']; // Error
tuple = ['hello', 10, 'world', 100]; // Error
  1. TypeScript는 function에도 Type을 선언할 수 있다. 타입 지정 대상은 함수로 전달되는 매개변수와 최종 리턴 값이 될 수 있다.
function split(str: string): string[] {
  return str.split('');
}
let myFn: (string) => string[] = split;
myFn = function() { }; // Type '() => void' is not assignable to type '(string: any) => string[]'. 
  1. 생성자 타입은 하나의 객체(클래스로부터 생성)가 여러 생성자의 시그니처로 구성될 때 포함할 수 있는 타입으로, 생성자 타입 리터럴을 사용해 정의한다.

메서드 시그니처(method signature)는 메서드의 선언부에 명시되는 매개변수의 리스트를 가리킨다. 만약 두 메서드가 매개변수의 개수와 타입, 그 순서까지 모두 같다면, 이 두 메서드의 시그니처는 같다고 할 수 있다.

참고자료 : 자바스크립트: 리터럴과 생성자

참고자료 : TypeScript 고급 타입

관련 조사를 찾던 중 알게 된 TypeScript 팁1!!

TypeScript class constructor Tip!

//이 예제에서는 constructor를 사용하여 기본 클래스에서 공용 속성 position 및 보호 된 속성 speed를 선언한다. 이러한 속성을 매개 변수 속성이라고 한다.
class Car {
    public position: number;        
    protected speed: number;

    constructor(position: number, speed: number) {
        this.position = position;
        this.speed = speed;
    }
    
    move() {
        this.position += this.speed;
    }        
}

//TypeScript는 관련 속성에 생성자 매개 변수를 자동으로 할당해준다.
class Car {
    constructor(public position: number, protected speed: number) {}
    
    move() {
        this.position += this.speed;
    }        
}

기타 타입

  1. union : 2개 이상의 타입을 하나의 타입으로 정의한 타입
var x: string | number;
  1. intersection : 두 타입을 합쳐 하나로 만들 수 있는 타입
interface Cat { leg: number; }
interface Bird { wing: number; }
let birdCat: Cat & Bird = { leg: 4, wing:2 };
  1. void : 빈 값을 나타내는 타입

  2. null, undefined 타입은 다른 모든 타입의 하위 타입(subtype)이다. tsconfig.json에서 strictNullChecks 옵션을 통해 할당을 방지할 수 있다.

  • undefined : 어떠한 빈 값으로도 초기화 되지 않는 타입
  • null : 빈 객체로 초기화됨
var person = { name: "happy" };
person = null;
console.log(typeof(person)); // object
  1. non-nullable : null이나 undefined 허용하지 않는 타입
  2. lookup type - keyof : keyof로 속성을 포함하는 대상을 찾아서 union type처럼 동작
interface exLookup { ex1: number; ex2: number; ex3: number; } 
type useLookup = keyof exLookup;
let real:useLookup = "ex2" // 허용

3. 자바스크립트의 타입

자바스크립트의 내장 타입

  • boolean
  • number
  • string
  • enum
  • symbol
let type1 = new Boolean(false); 
let type2= new Number(123);
let type3= new String("hello world");
type1.valueOf(); type2.valueOf(); type3.valueOf();

책을 보던 중 알게된 JavaScript 팁2!!
==는 값의 비교, ===는 값과 타입 동시에 비교

타입스크립트의 내장 타입

  • any

    any 타입은 제약이 없는 타입으로 어떤 타입의 값도 받아들일 수 있다. any 의 경우 타입 안정성이 떨어져서 의도치 않는 결과가 나올 수 있고, 그렇다고 한가지 타입으로만 정의하면 지정된 타입 이외에는 다른 타입을 받을 수 없다는 단점이 있다.
    noImpicitAny 옵션을 통해 사용을 강제할 수 있따.
    -> 나중에 등장하게 될 Generic 사용

  • object

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

let number = 50;
console.log(typeof number, number.toFixed(1)); // number, 50.0

let number2: Object = 50;
console.log(typeof number2, number2.toFixed(1)); //error 발생

let number3: any = 50;
console.log(typeof number3, number3.toFixed(1)); //number, 50.0
  • Array Type

    배열 타입은 요소 타입에 [ ]를 붙여 선언한다.

let myVar: string[] = ["banana","apple"];
  • Generic Array Type

    제너릭 배열 타입은 Array<T> 형태로 선언한다

let num: Array<number> = [1,2,3];
let num2: typeof num = [4,5,6]; //Type queries
  • Tuple Type

    튜플 타입은 n개의 요소로 이뤄진 배열에 대응하는 타입,

  • void, null, undefined Type

profile
FrontEnd Developer with React, TypeScript

1개의 댓글

comment-user-thumbnail
2021년 9월 2일

최고에요 !!!

답글 달기