그동안 타입스크립트를 쓴다고는 써왔는데, 어딘가 마음 한 구석이 허해서(?) 기초공부를 해봐야겠다고 마음 먹고 강의를 듣기 시작했다. 공부한 내용들을 정리해본다.
//call signature 만드는 방법1
type Add = (a:number, b:number) => number
//call signature 만드는 방법2
type Add = {
(a:number, b:number): number
}
type Push = {
(path: string): void
(config: Config): void
}
//call signature적용
const add:Add = (a,b) => a + b
type Config = {
path: string
state: number
}
type Push = {
(path: string): void
(config: Config): void
}
const push: Push = (config) => {
if(typeof config === "string") {
console.log("스트링")
} else {
console.log("컨피그")
}
}
//파라미터의 갯수가 다를 경우
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
}
//generic 적용
type SuperPrint = <T>(arr: T[]) => T
}
const superPrint: SuperPrint = (arr) => arr[0]
let a = superPrint(["a","b","c","d"])
let b = superPrint([1,2,3,4])
let c = superPrint([1,2,true,false])
...
//여러generic적용
type SuperPrint = <T,M>(arr: T[], b:M) => T
function superPrint<T>(a: T[]) {
return a[0]
}
//할당시에도 구체적으로 타입지정 가능
const a = superPrint<number[]>([1,2,3,4])
//유추하게 해도 된다.
const b = superPrint(["a", "b", "c", "d"])
//제네릭 사용의 다른예시
type Player<E> = {
name: string
extraInfo: E
}
//1 마치 props를 내려주듯 사용할 수 있다
const nico: Player<{ favFood: string }> = {
name: "nico",
extraInfo: {
favFood: "kimchi"
}
}
//2 1번 패턴의 응용
type NicoExtra = { favFood: string }
type NicoPlayer = Player<NicoExtra>
const nico: nicoPlayer = {
name: "nico",
extraInfo: {
favFood: "kimchi"
}
}
const lynn: Player<null> = {
name: "nico",
extraInfo: null
}
//리액트의 useState
const [state, setState] = useState<number>(0)
generic을 알고 보니 그동안 모호했던 코드들이 이해가 가기 시작했다. 타입스크립트를 이전에 쓰면서는 대체로 느낌과 경험에 의존했었는데(...) 제대로 된 이해를 이제야 한 것 같다. 역시 기초에 대한 탄탄한 공부가 중요하다는 사실을 새삼 다시 느끼게 되었다. 대충대충 넘어가지 말자!
공부한 강의
https://nomadcoders.co/typescript-for-beginners/lobby