seunghyun Note

Read TypeScript : Document (Everyday Types) 본문

스터디/Read TypeScript : Documentation

Read TypeScript : Document (Everyday Types)

승숭슝현 2024. 2. 19. 11:19

string, number, boolean

세 가지 원시 타입은 js에서 typeof 연산자를 사용하였을 때 얻을 수 있는 것과 같은 이름이다.

  • string : "abcd"
  • number : 1234 -> int, float은 존재하지 않는다.
  • boolean : true , false

Arrays

[1,2,3,4] 와 같은 배열 타입을 정할 때number[]` 구문을 사용 가능하다.

  • string[] 은 문자열 배열이다.

number[] = Array<number> 의 형태로 작성 가능하다. 이러한 형태를 제네릭 T<U>라고 한다.

Any

any는 특별한 타입이고 타입 검사 오류가 발생하는 것을 원하지 않을 때 사용 가능하다.

let obj: any = { x: 0 };
// 아래 이어지는 코드들은 모두 오류 없이 정상적으로 실행됩니다.
// `any`를 사용하면 추가적인 타입 검사가 비활성화되며,
// 당신이 TypeScript보다 상황을 더 잘 이해하고 있다고 가정합니다.
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;

타입이 any이면 해당 값에 대하여 임의의 속성에 접근할 수 있고 (return any) 함수인 것처럼 호출 가능하고 유효한 것이라면 무엇이든 할 수 있다.
결국 any는 코드상의 특정 라인에 문제가 없다고 안심시킨다는 목적 때문에 긴 타입을 새롭게 정의하고 싶지 않을 때 유용하게 사용할 수 있다.

noImplicaitAny

타입이 지정되지 않은 값에 대하여 TS가 타입을 추론할 수 없다면 컴파일러는 any타입을 부여하는 것이 기본 행위다.

noImplicitAny를 사용하면 암묵적으로 any로 간주하는 모든 경우에 오류를 발생시킨다.

Type Annotations on Variables

const, var,let 변수를 선언할 때 변수의 타입을 명시적으로 지정하기 위하여 타입을 추가할 수 있다.(선택사항)

let name : string = "seunghyun";
let id : number = 1234;

따로 작성하지 않으면 ts는 자동으로 타입을 추론해서 초깃값의 바탕으로 추론해준다.

let name = "seunghyun";
// type은 string으로 해준다

Function

Parameter Type Annotations

매개변수 타입은 매개변수 이름 뒤에 표기해야 한다.

function hello(name : string){
  console.log("Hello, "+ name.toUpperCase() +"!!")
}

매개변수 타입이 정해졌다면(string) 함수 검사를 이루어진다.

hello(123);
//error! number is not assignable to parameter of type 'string';

Return Type Annotations

반환 타입 또한 표기할 수 있다. 반환 타입 역시 매개변수 목록 뒤에 표기한다.

function countNumber(): number{
  return 2;
}

반환 타입은 표기하지 않아도 된다. 함수 내에 return문을 통해 반환 타입을 추론할 것이기 때문이다.
문서화를 목적으로 타입 표기를 수행하는 코드도 존재한다.

Anonymous Functions

const names = ["seung","hyun"];

// 함수에 대한 문맥적 타입 부여
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'?
});

문맥적 타입 부여 - 매개변수 s는 타입이 표기되지 않았음에도 불구하고 ts 는 s의 타입을 알아내기 위해 배열의 추론된 타입과 더불어 forEach함수의 타입을 활용했다.

Object Types

객체는 프로퍼티를 가지는 js값을 말한다.

// 매개 변수의 타입은 객체로 표기되고 있습니다.
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 });

매개변수 xy는 두 개의 프로퍼리로 이루어진 타입으로 표기된다. (두 값은 모두 number타입이다.)
또는 ;를 사용해서 구분한다.
타입을 지정하지 않는다면 any 타입으로 간주된다.

Optional Properties

객체 타입은 일부 또는 모든 프로퍼티의 타입을 선택적인 타입, 옵셔널로 지정할 수 있다.
?를 붙여서 사용한다.

function printName(obj: { first: string; last?: string }) {
  // ...
}
// 둘 다 OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });

Union Types

TS에서는 기존의 타입을 기반으로 다양한 연산자를 사용하여 새로운 타입을 만들 수 있다.

Defining a Union Type

  • 타입을 조합하는 첫 번째 방법은 유니언 타입을 사용하는 것이다.
    유니언 타입 : 서로 다른 두 개 이상의 타입들을 사용하여 만드는 것 , 타입 조합에 사용된 타입 중 무엇이든 하나를 타입으로 가질 수 있다.
function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// 오류
printId({ myID: 22342 });

Working with Union Types

유니언 타입의 멤버 중 하나에 해당하는 타입을 제공하면 된다.
TS에 유니언을 다룰 때는 해당 유니언 타입의 모든 멤버에 대하여 유효한 작업일 때에만 허용된다.
예를 들어 string | member 라는 유니언 타입일 경우, string타입에만 유효한 메서드는 사용할 수 없다(이해가 잘 안됨)

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

해결하기 위해서는 유니언을 좁혀야한다. TS는 string값만이 typeof연산의 결과값으로 "string"을 가질 수 있다.
결국 조건을 추가해줘야한다.

function printId(id: number | string) {
  if (typeof id === "string") {
    // 이 분기에서 id는 'string' 타입을 가집니다

    console.log(id.toUpperCase());
  } else {
    // 여기에서 id는 'number' 타입을 가집니다
    console.log(id);
  }
}

Type Aliases

똑같은 타입을 한 번 이상 재사용하거나 또 다른 이름으로 부리고 싶은 경우도 존재한다.

이와 같은 상황일 때 타입 별칭을 사용한다. (약간 class와 비슷한거 같다.)

type 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 });

타입 별칭은 객체 타입뿐이 아닌 모든 타입에 사용할 수 있다.

type ID = number | string;

Interfaces

인터페이스는 객체 타입을 만드는 다른 방법이다.

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 });

Differences Between Type Aliases and Interfaces

타입 별칭 vs 인터페이스 : 둘의 가장 큰 차이점은 타입은 새 프로퍼티를 추가하도록 개방될 수 없는 반면, 인터페이스의 경우 항상 확장 가능하다.

  • 인터페이스로 확장하기
interface Animal {
  name: string
}

interface Bear extends Animal {
  honey: boolean
}

const bear = getBear()
bear.name
bear.honey
  • 인터페이스에서 새 필드를 추가하기
interface Window {
  title: string
}

interface Window {
  ts: TypeScriptAPI
}

const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
  • 타입으로 확장하기(교집합을 통해)
type Animal = {
  name: string
}

type Bear = Animal & {
  honey: Boolean
}

const bear = getBear();
bear.name;
bear.honey;
  • 타입은 생성된 뒤에는 달라질 수 없다
type Window = {
  title: string
}

type Window = {
  ts: TypeScriptAPI
}

 // Error: Duplicate identifier 'Window'.

Type Assertions

타입 단언을 사용하면 타입을 좀 더 구체적으로 명시할 수 있다.

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");    //코드가 .tsx파일이 아닌 경우

ts는 불가능한 강제 변환을 방지한다.

const x = "hello" as number;
//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.

Literal Types

다행히 let , var은 있다. const는 불가능하다.

let changingString = "Hello World";
changingString = "Olá Mundo";
// 변수 `changingString`은 어떤 문자열이든 모두 나타낼 수 있으며,
// 이는 TypeScript의 타입 시스템에서 문자열 타입 변수를 다루는 방식과 동일합니다.
changingString;

const constantString = "Hello World";
// 변수 `constantString`은 오직 단 한 종류의 문자열만 나타낼 수 있으며,
// 이는 리터럴 타입의 표현 방식입니다.
constantString;

숫자 리터럴 타입 또한 같은 방식으로 사용할 수 있다.

function compare(a: string, b: string): -1 | 0 | 1 {
  return a === b ? 0 : a > b ? 1 : -1;
}

 

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html

 

Documentation - Everyday Types

The language primitives.

www.typescriptlang.org

 

728x90