타입스크립트의 기본타입

Written by 성기동 on
타입스크립트의 기본타입

가장 기본이 되는 타입들에 대해 알아봅니다.
타입스크립트 공식문서를 참조하여 타입스크립트의 가장 기본이 되는 타입들에 대해 알아보겠습니다.

boolean

true 혹은 false 값의 타입입니다.

const isAvailable: boolean = true;

number

숫자 값을 나타내는 타입입니다.

const numberOfPeople: number = 100;

숫자의 타입은 한 가지이기 때문에 소숫점을 포함한 것, 큰 숫자 등에 관계 없이 모두 number 타입을 사용합니다.

const largeNumber: number = 9007199254740991;
const pi: number = 3.14;

참고로 숫자 값에 대해서 numeric separator도 지원합니다.

const population: number = 50_000_000;

string

문자열에 대한 타입입니다.

const hello: string = "world";
const world: string = "hello";

single quotedouble quote은 기능적으로 동일하므로 같은 string타입을 사용합니다.
template literal로 생성된 문자열 또한 string 타입이됩니다.

const greeting: string = `Welcome ${user}, to our web site!`;

array

배열에 대한 타입입니다. 배열은 다른 타입들을 원소로 가지는 타입인데 두 가지 방법으로 표현할 수 있습니다.

const animals: string[] = ["cat", "dog", "cow"];

혹은,

const animals: Array<string> = ["cat", "dog", "cow"];

Array로 표현하는 방식은 보통 표현할 타입이 복잡할 때 많이 사용합니다.

const users: Array<{ name: string, age: number }> = [
  {
    name: "John",
    age: 23,
  },
  {
    name: "Jane",
    age: 24,
  },
];

만약 2차원 배열을 만든다면 이렇게 표현할 수 있습니다.

const matrix: number[][] = [
  [1, 2, 3],
  [4, 5, 6],
];

tuple

투플은 원소의 갯수가 정해진 배열의 타입입니다.
배열은 한 가지 타입의 원소가 무한하게(?) 포함될 수 있음을 표시하는데 반해 투플은 정해진 위치에 갯수 만큼의 원소를 표시하는데 사용합니다.

const countAndNames: [number, string, string, string] = [
  3,
  "James",
  "Jane",
  "John",
];

혹은 아래와 같이 표현하는 것도 가능합니다.

const countAndNames: [number, ...string[]] =
  [3, "James", "Jane", "John"];

물론 아래와 같이 표현했을 때는 계속해서 string 타입의 값을 추가할 수 있습니다.

const countAndNames: [number, string, string, string] =
  [3, "James", "Jane", "John", "Jason"]; // 길이가 맞지 않는다는 에러 발생
const countAndNames: [number, ...string[]] =
  [3, "James", "Jane", "John", "Jason"]; // OK

인덱스를 통해 접근할 때는 튜플을 통해 정의된 타입에 대해서는 해당 타입을 나타내지만 그 범위를 벗어났을 때는 튜플 내 타입들의 유니온타입으로 표시해줍니다.

const countAndNames: [number, string, string, string] = [
  3,
  "James",
  "Jane",
  "John",
];
countAndNames.push("Jason");
const string = countAndNames[3]; // string 타입
const numberOrString = countAndNames[4]; // number | string 타입

enum

enum은 자바스크립트에는 없는 데이터 타입으로서 특정 값들을 묶어서 관리할 수 있으며 아래와 같이 정의하고 사용할 수 있습니다.

enum Color {
  Red,
  Green,
  Blue
}
let c: Color = Color.Green;

이때 c의 타입은 Color가 되며 c에 저장되는 값은 숫자 1이 됩니다. 만약 첫 요소가 1부터 시작하도록 하고 싶다면,

enum Color {
  Red = 1,
  Green,
  Blue
}
let c: Color = Color.Green; // 2

와 같이 임의로 시작 값을 정할 수 있습니다. 또한 역으로 인덱스로 값을 가져올 수 있습니다.

enum Color {
  Red,
  Green,
  Blue
}
const firstColor = Color[0]; // 타입은 string, 값은 "Red"

필요에 따라 인덱스가 아닌 문자열을 이용해 enum을 만들 수도 있습니다.

enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}
let c: Color = Color.Green; // GREEN

any

타입스크립트의 타입 체킹 시스템은 서로 호환되지 않는 두 타입의 사용을 방지해줍니다.

let myNumber: number = 10;
myNumber = "Hello"; // Hello를 number 타입에 할당할 수 없다는 에러 발생

그런데 어떤 때는 해당 값의 타입을 모르거나 혹은 여러 가지 타입이 모두 허용되도록 하고 싶을 수 있습니다. 그럴 때 any를 사용할 수 있습니다.

let myNumber: any = 10;
myNumber = "Hello"; // no error

any는 주로 타입 정보가 없는 외부 라이브러리에 대한 타이핑하거나 혹은 자바스크립트와 타입스크립트를 혼용할 때 유용합니다. any를 남용하면 코드 분석에 타입체킹의 도움은 받을 수 없으므로 주의해야 합니다.

unknown

역시 any와 비슷하게 현재 타입 정보를 모를 때 사용합니다.
any와의 차이점은 해당 값을 사용할 때 타입을 확인해야 한다는 점입니다.
any의 경우 아래의 예시가 가능합니다만,

const printOut = (message: string) => {
  console.log(message);
}
const anyValue: any = "Hello";
printOut(anyValue); // no error
unknown은 불가능합니다.
const printOut = (message: string) => {
  console.log(message);
}
const unknownValue: unknown = "Hello";
printOut(unknownValue); // unknown 타입을 string 타입에 사용할 수 없다는 에러
대신 unknown 타입의 값이 사용 될 때 타이핑 정보를 제공해주어야 합니다.
if (typeof unknownValue === 'string') {
  printOut(unknownValue);
}

혹은 아래와 같이 강제로 지정해주는 것도 가능합니다.

printOut(unknownValue as string);
void
void는 어떤 타입과도 호환되지 않는 타입입니다. 주로 반환값이 없는 함수의 반환값에 대한 타이핑에 사용됩니다.
const printOut = (message: string): void => {
  console.log(message);
}

void로 타이핑된 변수에는 undefined만 할당할 수 있으므로 변수의 타이핑에는 거의 사용되지 않습니다.

null과 undefined

null과 undefined 타입은 자바스크립트에 있는 각각의 값에서 가져온 타입입니다.
역시 자기 자신 이외에는 할당할 수 없기 때문에 변수 할당에는 거의 쓰이지 않습니다.

let undefinedValue: undefined;
undefinedValue = "Hello"; // Hello를 undefined에 할당할 수 없음

그런데 옵션에 따라 null은 다른 타입의 서브타입처럼 동작하게 할 수 있습니다. 만약 strictNullChecks = false인 경우,

let myString: string = "Hello";
myString = null; // no error

와 같이 어떤 값이든 null로 만드는 것이 가능합니다.

never

never는 어떤 타입과도 호환되지 않는 타입입니다. 논리적으로 끝까지 실행될 수 없는 함수의 반환 값은 never타입이 됩니다.

const alwaysError = (): never => {
  throw new Error("Always error here");
};

if문 등으로 경우의 수가 좁혀진 변수의 경우 never타입이 될 수 있습니다.

const handleMultitypeValue = (myValue: string | number) => {
  if (typeof myValue === "string") {
    console.log("string:", myValue);
    return;
  }
  if (typeof myValue === "number") {
    console.log("number:", myValue);
    return;
  }
  return myValue; // never
};

object

object는 프로퍼티에 관계 없이 임의의 자바스크립트 오브젝트를 가리키기 위해 사용합니다.

const handleObject = (passedObject: object) => {
  // passedObject를 사용
};
handleObject({ hello: "World" });

타입 단언(type assertion)

대개의 경우에는 타입스크립트 컴파일러의 타입 추론(type inerence) 결과를 받아 들이고 이를 사용하여 프로그래밍을 할 수 있지만 컴파일러에게 제공된 타이핑 정보가 부족하다던가 혹은 타입스크립트의 기능상 한계 때문에 컴파일러의 제안을 무시하고 타입을 강제로 지정(type assertion)해야 할 때도 있습니다. 타입 단언을 하는 방법은 두 가지가 있습니다만,

<string>myValue.toLowerCase();
(myValue as string).toLowerCase();

jsx에서는 과 같은 문법은 사용할 수 없습니다.