如何将getter对象映射到它们的值?

时间:2017-12-06 12:55:20

标签: typescript

我有这个函数applyObject,我想要输入属性。函数的参数是TV,其中V是函数的对象:

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

T是我想要在应用时V的所有功能提供的类型。有没有办法做到这一点?

我认为使用映射类型是可能的,但我不确定。我这样想:

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

1 个答案:

答案 0 :(得分:2)

这个怎么样:

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}

我们的想法是根据输入对象类型V表达T类型,以及A的预期返回值类型applyObject()V<T,A>的键与A的键相同,值是从T到相应属性类型A的函数。此定义允许您使用inference from mapped types键入applyObject()

(这里有一点需要注意。如果你看到,我将A中的applyObject()参数定义为A extends any。这不是必需的;每种类型都延伸{{1在TypeScript中。但如果没有它,any会被推断为A,这并不是特别有用。我不知道为什么{a: any, b: any}修复它,但确实如此。有人更熟悉TypeScript类型推断的细节有什么想法?)

我还修改了实现,因为我更容易说服TypeScript它是类型安全的。如果您可以使TypeScript满意或强迫它沉默,请随意使用您自己的实现。

无论如何,希望有所帮助。祝你好运!