使用TypeScript

时间:2019-05-07 14:41:39

标签: typescript

我正在为OSS JS项目定义类型定义,并且需要在类型别名中推断“内部”类型。

有一种特定的类型可以是:

ActionFunc<State, Payload> = (state: State, payload: Payload) => State

直接从给定事件中获取有效负载。如果要将负载状态与自己的本地数据组合成不同负载类型,则可以改用:

[ActionFunc<State, ??>, (data: Payload) => ?]

这是一个在相同状态下包含AnctionFunc,但具有不同有效负载参数的元组,可以通过首先应用第二个元组来生成可以从常规Payload类型映射到自定义类型的项目。

该类型别名的天真版本类似于:

type Action<State, StandardPayload = {}, CustomPayload = void> =
    | ActionFunc<State, StandardPayload>
    | [ActionFunc<State, CustomPayload>, (payload: StandardPayload) => CustomPayload]

但是我遇到的问题是,它在外部公开了CustomPayload参数,从理论上讲应该可以推断并在内部一致地使用它,例如:

type Action<State, StandardPayload = {}> =
    | ActionFunc<State, StandardPayload>
    | [ActionFunc<State, infer CustomPayload>, (payload: StandardPayload) => CustomPayload]

只要ActionFuncpayload composer函数的参数类型 match ,我们就不在乎该类型是消费者/调用者。

>

当前的TS仅在infer条件类型的上下文中允许extends,但在这里我无法弄清楚哪种条件真正有意义。

1 个答案:

答案 0 :(得分:1)

您想要existentially quantified generic types,它们是not directly implemented in TypeScript(或其他大多数具有泛型的语言,以确保其价值。如果为{{3}启用语言扩展,甚至Haskell也只有supports them }}。)TypeScript仅具有 universally 量化的通用类型;像Foo<T>这样的通用量化泛型类型的实现/定义需要能够处理该类型的调用者/用户想要的T的任何可能值。存在类型会反过来:存在限定条件的通用类型(如(虚构语法)exists T. Foo<T>)的 caller / user 必须能够处理{{1}的任何可能值} 实现/定义想要的。从呼叫者的角度来看,您只能指定T对应于 some 类型(现有),而不是 any 类型(通用)。

那么,在没有直接支持存在的情况下,我们可以在TypeScript中做什么?好吧,我们可以通过反转带有函数和回调的控制来获得间接支持,这实际上将通用性转换为存在性,反之亦然。将其视为处理诸如承诺之类的东西,而不是处理其本身的价值:

T

这隐藏了type ActionPair<S, P, C> = [ActionFunc<S, P>, (payload: P) => C]; type ActionPairPromise<S, P> = { then<R>(onfulfilled: <C>(value: ActionPair<S, P, C>) => R): R; }; 参数,但是要使用它,您将必须在各处传递回调:

C

还有其他方法来代替存在性...您可以按照您所说的使用// turn a concrete ActionPair<S, P, C> into the existential ActionPairPromise<S, P> function actionPairToActionPairPromise<S, P, C>( actionPair: ActionPair<S, P, C> ): ActionPairPromise<S, P> { return { then(onfulfilled) { return onfulfilled(actionPair); } }; } // take the existential ActionPairPromise<S, P> and do something with it // namely, convert into an ActionFunc function actionPairPromiseToActionFunc<S, P>( value: ActionPairPromise<S, P> ): ActionFunc<S, P> { return value.then(actionPair => (state: S, payload: P) => actionPair[0](state, actionPair[1](payload)) ); } ,然后使接受此类类型的所有函数通用,并进行额外的检查以确保它符合某些类型any参数...

但是我在这里强烈怀疑,归根结底,使用C可以做到的唯一一件事就是将其转换为{{1 }}。那么为什么不这样做呢?

ActionPairPromise<S, P>

也就是说,您使用该类型的唯一位置是在转换为普通ActionFunc<S, P>并完成此操作的函数中。

无论如何,希望能帮到您一些想法。祝你好运!