打字稿中类型的通用映射 [英] Generic mapping of types in typescript

查看:92
本文介绍了打字稿中类型的通用映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们想象一下类型T:

lets imagine type T:

type T = {
  prop1: (s: S) => T1,
  prop2: (s: S) => T2,
  prop3: (s: S) => T3,
}

现在让我们想象一下类型W

and now lets imagine type W

type W = (s: S) => {
    prop1: T1,
    prop2: T2,
    prop3: T3,
}

易于编写将T映射到W的函数,

its easy to write a function that maps T to W by hand,

是否可以在打字稿中编写其通用类型的sefe版本?

is it possible to write generic type sefe version of it in typescript?

function x(t: T): W {
  return funtion(s: S) {
    prop1: t.prop1(s),
    prop2: t.prop2(s)
    prop3: t.prop3(s)
  }
}

缺少哪种功能语言来实现此目的,例如高阶通用类型?

what kind of feature language is missing to facilitate this, something like higher order generic types?

推荐答案

您确实可以在TypeScript中编写此版本的通用版本:

You can indeed write a generic version of this in TypeScript:

function x<S, V>(t: {[K in keyof V]: (s: S) => V[K]}): (s: S) => V {
  return function(s: S): V {
    const ret = {} as V;
    Object.keys(t).forEach((k: keyof V) => {
      ret[k] = t[k](s);
    })
    return ret;
  }
} 

const xSpecific: (t: T) => W = x; // okay

请注意,VW函数的返回类型. (因此W本质上与(s: S) => V相同.)x的输入是

Note that V is the return type of your W function. (So W is essentially the same as (s: S) => V.) And the input to x is a mapped type corresponding to T: it has the same keys as V, but its values are functions from S to the corresponding properties of V.

因为TypeScript支持提议的扩展typeof"功能的东西通常来自TW. (这可能是您所暗示的缺少的语言功能.)

You can get away with having the function input being a mapped type and the output being an unmapped one because TypeScript supports inference from mapped types. Otherwise you'd need something like the proposed "extended typeof" feature to derive W from T generically. (This might be the missing language feature to which you're alluding.)

对于实现,我遍历t的键并将每个功能t[k]应用于输入s.

As for the implementation, I'm looping over the keys of t and applying each function t[k] to the input s.

xSpecificx相同,只限于您发布的特定TW类型.进行编译是因为TypeScript识别出通用x是兼容的.

And xSpecific is the same as x narrowed to the particular T and W types you posted. This compiles because TypeScript recognizes that the generic x is compatible.

现在进行警告和精美印刷.不幸的是,编译器无法直接从x可靠地推断S的类型.如果仅使用T输入调用通用x(),则会得到以下信息:

Now for the caveats and fine print. Unfortunately, the compiler isn't able to reliably infer the type of S from x directly. If you just call the generic x() with a T input, you get this:

declare const t: T;
const w = x(t); // (s: {}) => { prop1: T1; prop2: T2; prop3: T3; }

w并不完全是W ...它接受任何输入,而不仅仅是S.如果您确实需要缩小输入类型,则必须自己手动指定通用参数来完成此操作:

The w is not exactly a W... it accepts any input, not just an S. If you really need to narrow the type of input, you'll have to do it yourself by manually specifying the generic parameters:

const w = x<S, {prop1: T1, prop2: T2, prop3: T3}>(t);

很难看,或者通过断言或注释手动缩小结果w:

which is ugly, or narrowing the resulting w manually by assertion or annotation:

const w: W = x(t);

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

Anyway, hope that helps. Good luck!

这篇关于打字稿中类型的通用映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆