【问题标题】:TypeScript overload and genericsTypeScript 重载和泛型
【发布时间】:2017-05-13 19:36:23
【问题描述】:

我确实有这门课:

class Container<T>
{
    prop<K extends keyof T>(key: K): BehaviorSubject<T[K]>
    {
        return null;    // something
    }

    obj<K extends keyof T>(key: K): Container<T[K]>
    {
        return null;    // something
    }
}

并像这样使用它:

interface Obj
{
    id: number;

    employee: {
        id: number;
        name: string;
    }
}

let container: Container<Obj>;
let id = container.prop('id');  // BehaviorSubject<number>
let employee = container.obj('employee');   // Container<{ id: number; name: string; }
let employeeName = employee.prop('name');   // BehaviorSubject<string>

现在我想要相同的东西(上面注释的变量类型),但我想对 prop 和 obj 使用相同的函数名。我想要一个基于属性类型切换返回类型的重载。

在 TypeScript 中可以吗?

【问题讨论】:

  • 您能否提供一个代码示例,说明您希望如何使用该函数(在两个propobj 函数合并后)?
  • 这将是一个动态检查事物的类的工作。我只想要一种将其映射到静态类型的方法。
  • 但是两个函数都需要相同的参数,你如何区分两者?
  • 对象将被预先创建,函数将只返回属性。恰好预先创建的数据与我想要的这些类型匹配。
  • 我已经向 TypeScript 提交了一个功能请求,以实现一个优雅的(恕我直言)方式来做到这一点github.com/Microsoft/TypeScript/issues/13214

标签: typescript typescript2.1 typescript2.2


【解决方案1】:

如果我理解你,那么你可以这样做:

class Container<T> {
    private value: T;

    ...

    get<K extends keyof T>(key: K): Container<T[K]> | BehaviorSubject<T[K]> {
        let value = this.value[key];

        if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
            // return a BehaviorSubject
        } else {
            // return a Container
        }
    }
}

问题当然是在使用这个Container.get时,你需要输入assert:

let id = container.get("id") as BehaviorSubject<number>;
let employee = container.obj("employee") as Container<{ id: number; name: string; };

【讨论】:

  • 我想要没有类型断言也没有额外属性(有交集类型)的东西。我尝试使用带有额外参数和默认值的重载函数,但也无法实现。
  • 如果签名都具有相同的精确参数(在本例中为key: K),则您不能有不同的签名,这是没有办法的。而且你不能没有类型断言,因为关于它是哪种类型的信息仅在函数体内可用。你最好坚持这两种方法。
猜你喜欢
  • 2021-05-21
  • 2021-04-23
  • 2021-11-19
  • 2022-12-03
  • 1970-01-01
  • 2022-01-26
  • 2013-06-16
  • 2017-11-05
  • 1970-01-01
相关资源
最近更新 更多