2017-12-06 2 views
1

나는이 기능을 유용하게 입력하고 싶습니다 applyObject 있습니다.Getter 객체를 값에 매핑하는 방법은 무엇입니까?

type V = { [key: string]: <R>(t: T) => R }; 

T 내가 적용될 때 V의 모든 기능을 통해 먹이고 싶은 유형입니다 : V이 기능의 목적은 어디 함수에 paramters는 TV의이다. 이 일을 할 수있는 방법이 있습니까?

매핑 된 유형이 가능하다고 생각하지만 확실하지 않습니다.

function applyObject<T, V extends { [key: string]: (t: T) => any }>(t: T, v: V) { 
    return Object.entries(v).reduce((applied, [_key, func]) => { 
    const key = _key as keyof V; 
    applied[key] = func(t); 
    return applied; 
    }, {} as {[P in keyof V]: Invoke<V[P]>}); // `Invoke` doesn't exist 
} 

const applied = applyObject(
    { one: 1, two: 'something' }, 
    { a: t => t.one, b: t => t.two } 
); 

applied.a; // should give intellisense as number 
applied.b // should give intellisense as string 
+0

나는 가능하지 않다고 생각한다. 문제는 'V'도 잘 입력되지 않았기 때문에,'V '의 모든 함수는'T'를 사용하고 어떤 타입을 반환 할 수 있다고 생각하고 싶다. , 그러나 당신이'R'을 정의하는 방식은 함수가 아닌 호출자의 몫입니다. –

+0

@ TitianCernicova-Dragomir 질문에서'R'을 삭제했습니다. 필요한지 확실하지 않습니다. –

답변

2

어떻게 이것에 대해 : I는 다음과 같이 생각하고

type V<T, A> = {[K in keyof A]: (t: T) => A[K]}; 
function applyObject<T, A extends any>(t: T, v: V<T, A>): A { 
    const ret = {} as A; 
    for (const k in v) { 
    ret[k] = v[k](t); 
    } 
    return ret; 
} 

const applied = applyObject(
    { one: 1, two: 'something' }, 
    { a: t => t.one, b: t => t.two } 
); // inferred as {a: number, b: string} 

아이디어는 입력 오브젝트 유형 T의 측면에서 V 유형을 표현하기 위해, 그리고 의도 반환의 종류 AapplyObject()의 값. V<T,A>의 키는 A의 키와 같으며 값은 T에서 적절한 속성 유형 A까지의 함수입니다. 이 정의를 사용하면 inference from mapped types을 입력하여 applyObject()을 입력 할 수 있습니다.

(이 여기에 조금주의해야 할 점은 그 필요는 없습니다 당신이 보는 경우에, 나는 A extends any을 할 applyObject()A 매개 변수를 정의이다,... 모든 유형의 타이프에 any를 확장하지만하지 않고, A{a: any, b: any}로 추정 도착하는 특히 유용하지 않습니다. 내가 왜 A extends any이 그것을 고쳐야하는지 전혀 모르겠다. TypeScript 타입 추론의 핵심에 대해 잘 알고있는 사람이라면 어떤 아이디어가 있겠는가?)

나보다 쉽게 ​​구현을 수정했다. TypeScript가 타입 안전하다는 것을 납득시키기 위해서입니다. TypeScript를 행복하게 만들거나 무음으로 만들 수 있다면 자신 만의 구현을 자유롭게 사용할 수 있습니다.

어쨌든 도움이 되길 바랍니다. 행운을 빕니다!

+0

당신은 마법사 –

+0

이고 typescript는'Array.prototype.reduce'의 리턴 값을 초기 누적기로 입력하므로'.reduce (/*...*/, {} as A)'가 효과가 있었을 것 같습니다 –

관련 문제