원시 타입

  • 자바스크립트에서 일반적으로 많이 쓰는 원시 타입으로 string, number, boolen이 있음
  • 타입스크립트에서도 각각 대응되는 타입이 있으며 타입 이름은 각 타입값에 typeof 연산자를 사용했을 때 얻을 수 있는 이름과 동일함
  • String, Number와 같이 대문자로 시작하는 타입역시 존재하지만, 이를 사용하는 경우는 드뭄
    항상 string, number같이 쓸것

배열

  • 배열의 타입을 지정할때는 number[] 와 같은 표기법을 사용함
  • 배열의 표기법은 모든 타입에서 동일하게 사용 가능
  • 제네릭을 사용해 Array<number>와 같은 표현법으로도 표기 가능

any

  • 타입 검사 오류가 발생하는것을 원하지 않을 때 사용 가능
  • 값이 any일 경우 값의 임의의 속성에 접근할 수 있고(반환값도 any) 함수처럼 호출도 가능하고, 다른 값에 할당받는 등 자바스크립트에서 가능한 모든 행동에 오류를 발생하지 않음
  • 타입스크립트 오류 해결만을 위해 긴 타입을 정의하고 싶지 않을 때 사용 가능
let obj: any = { x: 0 };
// 아래의 모든 코드에서 오류를 발생시키지 않음
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;

변수에 대한 타입 표기

  • 대부분의 경우 타입스크립트는 자동으로 코드 내에 있는 타입을 추론함
  • 만약 변수의 타입을 명시적으로 지정할 필요가 있으면 타입 표기를 추가할 수 있음
// 타입을 지정하지 않을 경우 a와 b는 any로 추론됨
const joinString = (a: string, b: string) => {
  return "a" + "b"
}

함수

  • 함수의 매개변수 뒤에 타입을 표기할 수 있음
function greet(name: string) {
  console.log("Hello, " + name.toUpperCase() + "!!");
}

greet(Minnie); // "Hello, MINNIE!!
greet(42); // Argument of type 'number' is not assignable to parameter of type 'string'.
  • 마찬가지로 반환 타입역시 표현 가능하며 매개변수 목록 뒤에 타입을 작성하면 됨
function getFavoriteNumber(): number {
  return 123;
}

익명 함수

  • 함수가 코드상에서 위치한 곳을 보고 함수가 어떻게 호출될지 알아낼 수 있으면 함수의 매개변수에 자동으로 타입을 부여함
    익명 함수에서 타입 추론이 발생하는 과정을 문맥적 타입 부여라고 함
const names = ["Alice", "Bob", "Eve"];
 
// forEach 함수의 타입을 통해 매개변수 s가 string임을 알아냄
names.forEach(function (s) {
  console.log(s.toUppercase());

});
/* Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'? */
 
// 화살표 함수에도 문맥적 타입 부여는 적용됨
names.forEach((s) => {
  console.log(s.toUppercase());
});
/* Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'? */

객체 타입

  • 객체 타입을 정의하기 위해서는 객체의 프로퍼티와 프로퍼티의 타입을 나열하기만 하면 됨
  • 프로퍼티의 타입을 지정하지 않으면 해당 프로퍼티는 any타입으로 간주함
//객체를 입력으로 받고 객체에 프로퍼티에 속성을 지정해줌
function printCoord(pt: { x: number, y: number }) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });
  • 객체 타입의 프로퍼티는 선택적인 타입(optional)로 지정할 수 있음
const deleteData = (dataRef: {imageRef?: String, DataRef: String) => {
  // 아래 코드가 없으면 Object is possibly 'undefined' 오류 발생
  if(imageData) deleteImg(imageData);
  // ...
}

유니언 타입

  • 유니언 타입을 사용해 두개 이상의 타입을 사용할 수 있음
    조합에 사용된 각각의 타입을 유니언 타입의 멤버라 부름
function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(123);

// OK
printId("apple");

// Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
printId({ myID: 123 });
  • 유니온 타입을 다룰 때에는 해당 유니언 타입의 모든 멤버에 대해 유효한 작업일 때만 가능함
// OK
function getFirstThree(x: number[] | string) {
  return x.slice(0, 3);
}

/* Property 'toUpperCase' does not exist on type 'string | number'.
  Property 'toUpperCase' does not exist on type 'number'. */
function printId(id: number | string) {
  console.log(id.toUpperCase());
}

//유니언을 좁혀 타입스크립트가 구체적인 타입을 추론할 수 있게 해주어야 함
function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id);
  }
}

타입 별칭

  • 타입을 재사용하고자 하는 경우에 타입에 새로운 이름을 부여할 수 있음
type Point = {
  x: number;
  y: number;
};

type ID = number | string;
  • 타입 별칭을 사용해도 형식이 같으면 같은 타입으로 처리함
type UserInputSanitizedString = string;
 
function sanitizeInput(str: string): UserInputSanitizedString {
  return sanitize(str);
}
 
let userInput = sanitizeInput(getInput());
userInput = "new input";

인터페이스

  • 객체 타입을 만드는 또 다른 방법
  • 타입 별칭과 마찬가지로 인터페이스는 익명 객체를 사용하는 것처럼 동작함
interface Point {
  x: number;
  y: number;
}
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });
  • 타입 별칭과 유사하지만 타입 확장을 클래스 확장과 유사하게 extends 구문을 써서 할 수 있고(교집합일 때는 &), 인터페이스 생성 이후에도 수정이 가능함
  • 만약 선언이 여러개 있을경우 여러개의 선언을 하나로 합치게 됨 (선언 병합)
  • 타입 별칭과 다르게 객체의 모양을 선언할 때만 사용 가능하며, 기존의 원시타입에 별칭을 붗일 때 사용할 수 없음

타입 단언

  • 어떤 타입이 들어올지 알고있는 경우에 타입 단언을 사용해 타입을 구체적으로 명시할 수 있음
    document.getElementById의 경우 타입스크립트는 HTMLElement중 하나가 반환된다는 사실만 알 수 있지만 타입 단언을 통해 HTMLFormElement가 들어온다는 사실을 알릴 수 있음
  • 타입 표기와 마찬가지로 타입 단언은 컴파일러에 의해 제거되며 코드의 실행에는 영향을 주지 않음
const loginForm = document.getElementById("loginForm"); as HTMLFormElement

// tsx파일이 아니면 다음과 같은 표기도 가능
const loginForm = <HTMLFormElement>document.getElementById("loginForm");

// 타입 변환시 한쪽의 타입은 다른 한쪽의 부분집합이여야 함, 아닐시 오류 발생
/* Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. */
const x = "hello" as number;

// 타입 변환이 꼭 필요하다면 any, unknown으로 우선 변환하고 원하는 타입으로 변환해주면 형변환이 가능함
const x = ("hello" as any) as number;
console.log(x) //"hello"

리터럴 타입

  • const 변수와 비슷한 느낌으로 타입을 지정할 때 타입뿐만 아니라 특정한 값만 들어올 수 있도록 지정할 수 있음
function printText(s: string, alignment: "left" | "right" | "center") {
  // ...
}
printText("Hello, world", "left");
printText("G'day, mate", "center");

// 리터럴이 아닌 타입과도 같이 사용 가능
interface Options {
  width: number;
}
function configure(x: Options | "auto") {
  // ...
}
configure({ width: 100 });
configure("auto"); 
  • 리터럴 타입은 리터럴값의 원래 타입과는 다른 타입으로 처리됨
// Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

// 타입을 단언하거나
const req = { url: "https://example.com", method: "GET" as "GET" };
handleRequest(req.url, req.method);

// as const를 사용해 객체 전체를 리터럴 타입으로 변환해 문제 해결 가능
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);

null과 undefined

  • strictNullChecks 옵션의 설정 여부에 따라 동작 방식이 달라짐
  • strictNullChecks가 설정되지 않으면 어떤 값이 null, undefined일 수 있어도 해당 값을 평소와 같이 사용 가능 (권장하지는 않음)
  • strictNullChecks가 설정되어 있으면 어떤 값이 null, undefined일 수 있으면 null값에 대한 오류를 사전에 검사해야 함
function setProfile(nickname?: string) {
  if (!nickname) throw window.alert("no nicknamedata");
  //...
}

// null과 undefined가 아닌 것이 확실한 경우 ! 연산자를 사용해 null과 undefined를 제거 가능
function getId(token?: string) {
  //대충 id 받아왔다는 내용
  console.log(data!.id);
}

열거형

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

Reference

  • 어떤 값이 이름이 있는 상수 지밥에 속한 값 중하나일 수 있도록 제한하는 기능
  • 타입스크립트가 자바스크립트에 추가하며 런타입시에도 제거되지 않음

bigint & symbol

  • bigint: 아주 큰 정수를 다루기 위한 원시 타입, ES2020 이후부터 사용 가능
  • symbol: 전역적으로 고유한 참조값을 생성하는데 사용할 수 있음
//bigint
const oneHundred: bigint = BigInt(100000000);
const anotherHundred: bigint = 100000000n;

//symbol
const firstName = Symbol("name");
const secondName = Symbol("name");
 
/* This condition will always return 'false' since the types 'typeof firstName' and 'typeof secondName' have no overlap.*/
if (firstName === secondName) {
	//...
}
profile
냐아아아아아아아아앙

0개의 댓글

Powered by GraphCDN, the GraphQL CDN