export const functions = {
add: (a: number, b: number) => a + b,
pow: (a: number) => a * a,
twice: (a: string) => a + a,
}
const createMessagePassing =
<T extends Record<string, F>, F extends (...args: any[]) => any = any>(t: T) =>
<K extends keyof T>(k: K, ...p: Parameters<T[K]>): ReturnType<T[K]> =>
t[k](...p)
const runFunctions = createMessagePassing(functions)
보기 좋으라고 개행 넣긴했는데
코드 한줄이면 끝남
안쓰는 디퐅트 인자 any 넣어서 코드 압축한건데 따로 메타함수 빼서 type inference + 안맞으면 never 처리하면 두줄로 끝남
T를 나중에 넣어줘서 오류가 안생기는것같네
T는 그냥 typeof functions로 해줘도 됨 T[keyof T] 이게 요령 - dc App
T[keyof T]가 핵심같지는 않은게 type T = typeof functions; type K = keyof T; const createMessagePassing = (k: K, ...p: Parameters): ReturnType => functions[k](...p); 이거 에러남 T를 나중에 넣어서 오류가 안생긴다고 한게 무슨말이냐면 원래 코드에서는 functions의 타입이 알려져있기 때문에 f가 (a: never, b: number) => string | number로 추론돼서 함수콜에서 타입오류가 뜨는데 니 버전에서는 t[k]가 (...args: any[]) => any로 추론돼서 오류가 안뜸. 그 차이 얘기한거
그건 함수 제네릭 인자가 아니라 따로 타입을 밖에 선언한거라 파라미터가 문자열 리터럴로 들어왔을때 타입을 한정시키는 동작이 아니라 외부에 선언된 유니온으로 들어와서 그럼 - dc App
타입을 외부에 선언하면 상수 인자 K를 줘도 T에 매핑시킬때 정확한 상수타입 정보가 사라져버림 - dc App
K extends keyof T랑 keyof T 차이 - dc App
아 ㅇㅋ K = keyof T가 문제인건 알겠음
type T = typeof functions; const createMessagePassing = “K extends keyof T”(k: K, ...p: Parameters“T[K]”): ReturnType“T[K]” => functions[k](...p); 다시 돌아와서 요점은 여기서 T가 미리 주어졌기 때문에 오류가 난다는거지
이건 아마 인자 ...p 타입이랑 리턴타입의 연결고리가 없어서 에러가 난걸거임 내 코드는 any로 한 번 타입이 사라졌다가 나중에 달아주는 방식이라 에러가 안난걸거고
이거 any 안쓰고 하면 메타함수로 createMessagePassing 함수 타입 자체를 만든다음에 입혀야함 함수에 타입 다는 표현으로는 어렵고 infer 로 처리하면서 파라미터랑 리턴 연결하고 아닌케이스 never로 걸러내는 작업 해야할거임
직접 쳐보니까 함수 시그니쳐에서는 괜찮은데 구현부에서 p 인자를 튜플로 못알아먹네 이건 그냥 언어가 좀 구려서 그런듯 생각해보니까 연결고리가 없으면 에러까진 안가고 리턴타입이 유니온으로 나오겠다
마치 정규표현식 마스터한 사람이 복잡한 정규표현식 짠 느낌이라 이해가 아예 안댐 + - dc App
고마워 ㅜㅜ