V-logue

[Typescript] 노마드코더 TypeScript로 블록체인 만들기 (3-3) 본문

발자취/Typescript

[Typescript] 노마드코더 TypeScript로 블록체인 만들기 (3-3)

보그 2022. 9. 7. 23:20

Generic Recap

 

type SuperPrint = <x>(a:x[]) => x

const superPrint : SuperPrint = (a) => a[0]

const a = superPrint([1 ,2 , 3, 4]);
const b = superPrint([true, false, true, false]);
const c = superPrint(["a", "b", "c", "d"]);
const d = superPrint([1,"2",true,"hello"]);

3-2강의에서 제네릭(Generic)이 placeholer를 사용해서 작성한 코드의 타입을 추론한다는 것을 알게 됐다.
ts는 내 코드를 보고, superPrint가 placeholder를

각 a,b,c,d의 배열마다 있는 요소에서 발견된 타입으로 대체한다는 것을 알 수 있다.
x라는 제네릭을 사용할 거라고 ts에 알렸고, x는 배열에서 오고 함수의 첫번째 파라미터에서 오는 거라고
ts에 알려준 것이다. ts는 이걸 기반으로, 각 배열의 첫번 째 element를 살펴보고
각 배열의 첫번 째 인덱스의 타입을 추론한다.

 

만약 SuperPrint가 any라면

 

type SuperPrint =   (a:any[]) => any

const superPrint : SuperPrint = (a) => a[0]

const a = superPrint([1 ,2 , 3, 4]);
const b = superPrint([true, false, true, false]);
const c = superPrint(["a", "b", "c", "d"]);
const d = superPrint([1,"2",true,"hello"]);
d.toUpperCase();

// d.toUpperCase()에 에러가 발생해야 하는데도 발생하지 않는다.

a, b ,c, d 모두 any타입으로 변경됐고
위 사례의 경우 d의 첫번째 인덱스인 Number를 대문자로 바꿀 수 없기 때문에 문제가 발생한다.
위와 같은 상황을 방지하기 위해 제네릭을 사용한다.

 

type SuperPrint = <x>(a:x[]) => x

const superPrint : SuperPrint = (a) => a[0]

const a = superPrint([1 ,2 , 3, 4]);
const b = superPrint([true, false, true, false]);
const c = superPrint(["a", "b", "c", "d"]);
const d = superPrint([1,"2",true,"hello"]);
c.toUpperCase();

type을 any에서 generic으로 변경했을 경우 d.toUpperCase()에 다음과 같은 에러가 발생한다.
'string | number | boolean' 형식에 'toUpperCase' 속성이 없습니다.
  'number' 형식에 'toUpperCase' 속성이 없습니다.
위와 같은 형식의 사용을 막아주는 것이다. c.toUpperCase()하면 에러가 발생하지 않는다.

 

이제 superPrint type 제네릭을 하나 더 추가하고 싶다면 어떻게 해야 할까?

type SuperPrint = <x,y>(a:x[], b:y) => x

const superPrint : SuperPrint = (a) => a[0]

const a = superPrint([1 ,2 , 3, 4], "x");
const b = superPrint([true, false, true, false], 1);
const c = superPrint(["a", "b", "c", "d"], false);
const d = superPrint([1,"2",true,"hello"], []);

<x>에 y를 추가하고, 어디서 새로운 제네릭을 사용할 것인지 명시한다.
a:x[], b:y 이런식으로 2번째 인수에 y를 사용할 것이라고 명시한다.

Comments