[Typescript] 타입스크립트로 블록체인 만들기 강의 학습 #3

jhcha·2023년 7월 28일
0

Typescript

목록 보기
3/8
post-thumbnail

Functions

const add(a: number, b: number): number{
	return a+b;
}
const add = (a: number, b: number): number => a+b

Call Signatures

type Add = (a: number, b: number) => number;
const add:Add = (a, b) => a + b

overloading

overloading은 서로 다른 여러개의 call signatures이 있을 때 발생한다.

type Config = {
	path: string,
    state: object
} 
type push = {
	path: string,
    config: Config
}
const push: Push = (config) => {
	if(typeof config == "string") console.log(config);
    else{
    	console.log(config.path);
    }
}
type Add = {
	(a: number, b: number): number
	(a: number, b: number, c: number): number
}
const add:Add = (a, b, c?: number) => {
    if(c) return a+b+c 
    return a+b;

}

polymorphism (다형성)

type SuperPrint = {
	(arr: number[]): void
    (arr: boolean[]): void
    (arr: (number|boolean)[]): void
}
const superPrint: SuperPrint = (arr) => {
	arr.forEach(i => console.log(i));
}
superPrint([1, 2, 3]);
superPrint([true, false, true]);
superPrint([1, 2, true, false]);

how to add String Array Parameter?

배열을 입력받아 배열의 모든 원소를 출력하는 superPrint function을 만든다.
하지만, superPrint 함수에 모든 타입의 call signature를 추가하는 것은 비효율적이다.

제네릭 타입은 입력된 타입 기준으로 타입을 변경시켜준다. 따라서, 다양한 타입에 대한 call signature을 선언하지 않고 제네릭 타입을 사용하면 코드가 더욱 간결해진다.

type SuperPrint = {
	<TypePlaceHolder>(arr: TypePlaceHolder[]): void
}
const superPrint: SuperPrint = (arr) => {
	arr.forEach(i => console.log(i));
}
// 제네릭은 입력 타입에 대한 call signature를 자동으로 생성한다.
superPrint([1, 2, 3]);
superPrint([true, false, true]);
superPrint([1, 2, true, false]);

입력받은 배열의 첫 번째 요소를 반환하기 위해 제네릭을 사용할 수 있다.

type SuperPrint = {
	<TypePlaceHolder>(arr: TypePlaceHolder[]): TypePlaceHolder
}
const superPrint: SuperPrint = (arr) => arr[0]

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

any와 generic은 비슷한 것 처럼 보이지만, generic은 입력에 해당하는 타입 기준으로 타입을 변환시켜서 동작하지만, any는 단지 어느 타입이든 신경쓰지 않기 때문에 에러가 발생할 수 있다.

type SuperPrint = {
	(a: any): any
}
const superPrint: SuperPrint = (a) => a[0]
const d = superPrint([1, 2, true, "string"]);
d.toUpperCase() // d가 number 형태이지만, 인지하지 못하기 때문에 에러가 발생한다.
type SuperPrint = {
	<T, M>(a: T[], b?: M): T|M
}
const superPrint: SuperPrint = (a, b) => {
	if(b) return b;
    return a[0]
}

const a = superPrint(["string", 2, true, false], 3);

타입스크립트는 제네릭을 처음 인식했을 때와 제네릭의 순서를 기반으로 제네릭의 타입을 알게 된다.

function superPrint<T>(a: T[]){
  return a[0];
}

// 타입을 반드시 명시할 필요 없고, 타입스크립트가 타입을 추론하는 것이 권장됨
const a = superPrint<number>([1, 2, 3]);
const b = superPrint([1, 2, 3]);
type Player<E> = {
	name: string
    extraInfo: E
}
const jh: Player<{favFood:string}> = {
	name: "jhcha",
    extraInfo: {
    	favFood: "kimchi"
    }
}

type JhExtra = {
	favFood: string
}
type JhPlayer = Player<JhExtra>
const jh: Player<{favFood:string}> = {
	name: "jhcha",
    extraInfo: {
    	favFood: "kimchi"
    }
}
const lynn: Player<null> ={
	name: "lynn",
    extraInfo: null
}
// type A = Array, 타입스크립트 내장 Arr가 <T> 제네릭을 사용하는 것을 확인할 수 있음
type A = Array<number>

ley a:A = [1,2,3,4]

function printAllNumbers(arr: number[]){ ... }
function printAllNumbers(arr: Array<number>){ ... }

타입스크립트 표준 라이브러리의 Array는 제네릭을 사용한다. 따라서, arr: number[] 대신 Array로도 사용할 수 있음.

0개의 댓글