JAVASCRIPT/타입스크립트
TS. Function
(*ᴗ͈ˬᴗ͈)ꕤ*.゚
2022. 6. 29. 14:37
1. Call Signature
// ERR -> a, b가 any타입이기 때문
function add(a, b){
return a + b;
}
// ALLOWED
function add(a:number, b:number){
return a + b;
}
// ALLOWED
const add = (a:number, b:number) => a+b
// Call signatures
type Add = (a:number, b:number) => number;
const add:Add = (a,b) => a + b
// Call signature 에러 조심 (중괄호)
const add:Add = (a,b) => {a + b} // -> void
2. Overloading(오버로딩)
여러 개의 Call Signatures를 가질 때 주로 발생
// Allowed
type Add = {
(a: number, b: number): number
}
const add: Add = (a, b) => a + b
// Err
type Add = {
(a: number, b: number): number
(a: number, b: string): number
}
const add: Add = (a, b) => a + b
// Allowed
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
}
2-1. Next.js
// Next.js에서의 활용 사례
Router.push({
path: "/home",
state: 1
})
.push("/home")
type Config = {
path: string,
state: object
}
type Push = {
(path:string): void
(config: Config): void
}
const push:Push = (config) => {
if(typeof config === "string"){
console.log(config)
} else {
console.log(config.path, config.state)
}
}
2-2. arguments가 다를 때
type Add = {
(a: number, b: number): number
(a: number, b: number, c:number): number
}
// case 1 -> ERR
const add:Add = (a, b, c) => {
return a + b
}
// case 2 -> ERR
const add:Add = (a, b, c:number) => {
return a + b
}
// case 3 -> Allowed
const add:Add = (a, b, c?:number) => {
return a + b
}
// case 4 -> Allowed
const add:Add = (a,b,c?:number) => {
if(c) return a + b + c
return a + b
}
3. Polymorphism (다형성) // Generics
// 예시
type SuperPrint = {
(arr:number[]): void
(arr:boolean[]): void
(arr:string[]): void
}
const superPrint: SuperPrint = (arr) => {
arr.forEach(i => console.log(i))
}
// Allowed
superPrint([1,2,3,4])
superPrint([true, false, true])
superPrint(["a", "b", "c"])
// ERR
superPrint([1,2,true,false])
// ERR
superPrint([1,2,true,false])
// ERR -> Allowed로 바꾸는 방법 (1) : call signiture 추가
type SuperPrint = {
(arr:number[]): void
(arr:boolean[]): void
(arr:string[]): void
(arr:(number|boolean)[]): void
}
// ERR -> Allowed로 바꾸는 방법 (2) : Genireics 사용 ( = Call Signature 생성)
type SuperPrint = {
<TypePlaceholder>(arr:TypePlaceholder[]): void
}
// Allowed
type SuperPrint = {
<TypePlaceholder>(arr:TypePlaceholder[]): TypePlaceholder
}
const superPrint: SuperPrint = (arr) =>arr[0]
const a = superPrint([1,2,3,4])
const b = superPrint([true, false, true])
const c = superPrint(["a", "b", "c"])
const d = superPrint([1,2,true,false])
any와 generic 공통점
- 어떤 타입이든 받을 수 있다
any와 generic 차이점
- any: 함수를 반환하는 데 있어서 받았던 인수들의 타입을 활용하지 못한다
- generic: 타입에 대한 정보를 다른 쪽으로 전달할 수 있다
두 개의 arguments
type SuperPrint = <T, M>(a: T[], b:M) => T
const superPrint : SuperPrint = (a) => a[0]
// Allowed
const a = superPrint([1, 2, 3, 4], "x")
//Expected 2 arguments, but got 1.
const b = superPrint([true, false, true])
function으로 표현
function superPrint<V>(a: V[]){
return a[0]
}
// ALLOWED
const a = superPrint([1, 2, 3, 4])
// ERR (Gererics로 선언했으나, number이라 덮어쓰기 했으므로...)
const b = superPrint<number>([true, false, true])
활용법
type Player<E> = {
name: string
extraInfo: E
}
const nico : Player<{favFood: string}> = {
name: "nico",
extraInfo: {
favFood: "kim"
}
}
type Player<E> = {
name: string
extraInfo: E
}
type NicoPlayer = Player<{favFood: string}>
const nico : Player<{favFood: string}> = {
name: "nico",
extraInfo: {
favFood: "kim"
}
}
type Player<E> = {
name: string
extraInfo: E
}
type NicoExtra = {
favFood: string
}
type NicoPlayer = Player<NicoExtra>
const nico : Player<{favFood: string}> = {
name: "nico",
extraInfo: {
favFood: "kim"
}
}