[TS] Functions

강원지·2023년 3월 6일
0

타입스크립트

목록 보기
2/4

return 타입 쓰지 않아도 알아서 유추함

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

Call Signatures

Call(=Function) Signature를 통해 함수의 매개변수와 반환 값의 타입을 모두 type으로 미리 선언

type Add = {
	(a: number, b: number): number;
}
// type Add = (a: number, b: number) => number;

const add: Add = (a, b) => a + b
//const add: Add = (a, b) => {a + b} : return이 void기 때문에 type error

Overloading

: 직접 작성하기보다 외부 라이브러리에 자주 보이는 형태로, 하나의 함수가 복수의 Call Signature를 가질 때 발생한다

type Add = {
	(a: number, b: number): number,
	(a: number, b: string): number
}

const add: Add = (a, b) => {
	if (typeof b === "string") return a;
	return a + b;
}

매개변수의 데이터 타입이 다른 경우 예외 처리

type Add2 = {
	(a: number, b: number): number,
	(a: number, b: number, c: number): number
}

const add2: Add2 = (a, b, c?: number) => {//c는 옵션지만 쩄든 숫자임
  //매개변수의 수가 다른 경우, 나머지 파라미터 c도 타입지정 필수
	if (c) return a + b + c;
	return a + b;
}

위와 같은 함수는 거의 없지만 외부 라이브러리에서 활용될 수 있음.

아래 Next.js의 예시는 자주 쓰임.

router.push("/home");

router.push({
path: "/home",
state: 1
});

예를 들어, Next.js의 라우터 push가 대충 두 가지 방법으로 페이지를 이동한다고 할 때,

type Config = {
	path: string,
	state: number
}

type Push = {
	(config: Config): void,
	(config: string): void
}

const push: Push = (config) => {
	if (typeof config === "string") console.log(config);
	else console.log(config.path);
}

Polymorphism

concrete type

: number,string,void 등

type SuperPrint={
  (arr:number[]):void
  (arr:boolean[]):void
}
const superPrint:SuperPrint=(arr)=>{
  arr.forEach(i=>console.log(i));
}
superPrint([1,4,2,3]);
superPrint([true,false]);
superPrint([1,2,true])//이 arguments에 대한 call signature은 없기 때문에 동작x

generic

: 타입의 placeholder => 무슨 타입인지 불확실할 때 사용, TS가 유추가능

type SuperPrint={
  <TypePlaceholder>(arr:TypePlaceholder[]):void//Generic은 <T>를 주로 사용함
  //<T>(a:T[])=>void
}
  ...
superPrint([1,4,2,3]);//이 라인에서 인자들의 타입을 알게 됨
superPrint([true,false]);
superPrint([1,2,true])//(arr:(number|boolean)[]):void 타입을 가짐
type SuperPrint={
  <TypePlaceholder>(arr:TypePlaceholder[]):TypePlaceholder
  //맨앞에 <T> 선언 필수
}
const superPrint:SuperPrint=(arr)=>arr[0]
const num1=superPrint([1,2,3])//num1의 타입은 number
const num2=superPrint([1,true,"d"])//num2의 타입은 number
//const superPrint: <string | number | boolean>(arr: (string | number | boolean)[]) => string | number | boolean

any와의 차이점
generic은 해당 타입에 대한 정보를 잃지 않는다.
any는 any로서 밖에 알 수 없지만 generics는 타입 정보를 알 수 있다.

const SuperPrint=<T,M>(a:T[],b:M)=>T

간단한 제네릭 사용법

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

제네릭 타입 재사용

type Player<T> = {
	name: string,
	extraInfo: T
};

type NicoExtra = {age: number};
type NicoPlayer = Player<NicoExtra>;


const player: NicoPlayer = {
	name: "joseph",
	extraInfo: {
		age: 23
	}
};

const player2: Player<null> = {
	name: "Yee",
	extraInfo: null
};

TS가 타입을 유추할 수 있도록 작성하자.

0개의 댓글