首页 > 解决方案 > 在 Typescript 中处理多态值

问题描述

我正在尝试在 Typescript 中编写一些解析器。我的解析器都是基类的实例,Parser由类型A和参数化S,表示解析结果和解析器状态。

class Parser<A, S> {
  parse: (state: S) => Response<A, S>

  constructor(parse: (state: S) => Response<A, S>) {
    this.parse = parse

  // various combinator methods...
}

在我感兴趣的几个案例中,我希望状态S能够适应解析字符串,并且还可以携带一些用户可定义的类型的有效负载U。因此,S感兴趣的可能实现:

interface SS<U> {
   str: string;
   user: U
}

然后我想构建我能想到的最基本的解析器:char. 它消耗并返回正在解析的字符串中的第一个字符(如果有),或者如果没有则失败。因此,我想

char: Parser<string, SS<U>>

对于任何U.

但是,唉,Typescript 不允许涉及泛型的,只允许函数、类等。 [ “变量不能有自由的泛型”,正如 Titian 在下面的评论中所说的那样。] phA 有任何标准模式可以规避这个局限性?我能想到的唯一“解决方案”是:

  1. char做成一个函数function char<U>(): P<U> {...; return realChar}:. 我觉得这种解决方法并不吸引人,因为每次运行时都会产生运行时成本char()

  2. 将我所有依赖于U函数的解析器包装起来:

    function parsers<U>() {
        let char: Parser<string, SS<U>> = ...
        let letter: Parser<string, SS<U>> = ...
        let digit: Parser<string, SS<U>> = ...
        // other parsers
        return {char, digit, letter, ...}
    }
    

    然后我可以在使用它们时通过运行来实例化它们,parsers()并且手头有混凝土 U

是否有任何其他更优雅或产生最小运行时开销或已建立模式的方法?[任何人都知道 Typescript 路线图上是否有类似“泛型类型的值”(有更好的术语吗?)?]

标签: typescriptclassgenericstypespolymorphism

解决方案


推荐阅读