// 함수
function add(a: number, b: number): number {
return a + b
}
// 함수의 매개변수는 타입을 추론하지 않는다.
// 반환 타입은 자동으로 추론하지만 원하면 명시 할 수 있다.
// 함수을 구현하는 표현식
// 이름을 붙인 함수
function greet(name: string) {
return 'hello ' + name
}
// 함수표현식
let greet2 = function(name: string) {
return 'hello ' + name
}
// 화살표 함수 표현식
let greet3 = (name: string) => {
return 'hello ' + name
}
// 단축형 화살표 함수 표현식
let greet4 = (name: string) => 'hello' + name
// 함수 생성자
let greet5 = new Function('name', 'return "hello" + name')
// 선택적 매개변수와 기본 매개변수 매개변수에 물음표? 선택
function log(message: string, userId?: string) {
}
// 기본 매개변수
function log2(message: string, userId = 'Not') {
}
// 매개변수에 타입 지정
type Context = {
appId?: string
userId?: string
}
function log3(message: string, context: Context = {}) {
}
// 배열
function sum(numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0)
}
sum([1, 2, 3])
// 동적 매개변수
function sum1(...numbers: number[]): number {
console.log('sum1')
return 1
}
sum1(1, 2, 3)
// call, apply, bind
// 함수를 괄호()로 호출하는 방법도 있지만 다른 방법이 있다. call, apply
sum1(0, 1)
sum1.apply(null, [0, 1])
sum1.call(null, 0, 1)
sum1.bind(null, 10, 20)() // bind는 함수를 호출하지 않고 새로운 함수를 반환
// this
function fancyDate(this: Date) {
return this.getDate()
}
fancyDate.call(new Date)
// fancyDate(new Date) error this가 void 타입으로 에러
// 제너레이터 함수
function* createFibonaciGenerator() {
let a = 0
let b = 1
while(true) {
yield a;
[a, b] = [b, a + b]
}
}
let generator = createFibonaciGenerator()
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
// 반복자
// 반복자(iterable) vs 제너레이터는 상생 관계다
// 호출 시그니처
function sum3(a: number, b: number): number {
return a + b
}
// (a: number, b: number ) => number // 호출시그니처, 타입시그니처
type Log = (message: string, userId?: string) => void
let logger: Log = (
message, userId = "Not"
) => {
let time = new Date().toISOString()
console.log(time, message, userId)
}
logger("hihihi", "123")
// 문맥적 타입화
function times(
f: (index: number) => void,
n: number
) {
for (let i = 0; i < n; i++) {
f(i)
}
}
times(n => console.log(n), 4)
// 오버로드 된 함수
type Reserve = {
(from: Date, to: Date, destination: string): void,
(from: Date, destination: string): void
}
let reserve: Reserve = (
from: Date,
toOrDetination: Date | string,
destination?: string
) => {
}
// 다형성
function filter(array: number[], f: (item: number) => boolean ) {
let result = []
for (let i = 0; i < array.length; i++) {
let item = array[i]
if (f(item)) {
result.push(item)
}
}
return result
}
filter([1, 2, 3], _ => _ < 3)
// filter([1, 2, 3], function(a: number) {return true})
type Filter = {
(array: number[], f: (item: number) => boolean): number[]
(array: string[], f: (item: string) => boolean): string[]
// (array: object[], f: (item: object) => boolean): object[] 오류가 날 개연성이 있다
}
let names = [
{ firstName: 'a'},
{ firstName: 'b'},
{ firstName: 'c'}
]
// let result: Filter = filter(names, _ => _.firstName.startsWith('b'))
// result[0].firstName
// 제네릭 타입 매개변수
type Filter2 = {
<T>(array: T[], f: (item: T) => boolean): T[]
}
// let fileter2: Filter2 = (array, f) => return true//
let filter2: Filter2 = (array, f) => {
let result = []
for (let i = 0; i < array.length; i++) {
let item = array[i]
if (f(item)) {
result.push(item)
}
}
return result
}
filter2([1, 2, 3], _ => _ > 2)
filter2(['a', 'b', 'c'], _ => _ !== 'b')
filter2(names, _ => _.firstName.startsWith('b'))
// type Filter<T> = {
// (array: T[], f: (item: T) => boolean): T[]
// }
// type Filter = <T>(array: T[], f: (item: T) => boolean): T[])
// type Filter<T> = (array: T[], f: (item: T) => boolean) => T[]
// function map(array: unknow[], f: (item: unknown) => unknown): unknown[] {
// let result = []
// for (let i = 0; i < array.length; i++) {
// result[i] = f(array[i])
// }
// return result
// }
function map<T, U>(array: T[], f: (item: T) => U): U[] {
let result = []
for (let i = 0; i < array.length; i++) {
result[i] = f(array[i])
}
return result
}
console.log(map(
['a', 'b'], // T 타입의 배열
_ => _ === 'a' // U 타입을 반환하는 함수
))
// 제네릭 타입 별칭
type MyEvent<T> = {
target: T
type: string
}
type TimedEvent<T> = {
event: MyEvent<T>
from: Date
to: Date
}
function triggerEvent<T>(event: MyEvent<T>): void {
//
}
triggerEvent({target: document.querySelector('#mybutton'), type: 'mouseover'})```