【问题标题】:Inferring return type from generic type?从泛型类型推断返回类型?
【发布时间】:2020-08-24 10:44:22
【问题描述】:

以下方法有效,但 .getData() 的返回类型为 any,这并不理想,因为这是消费者面孔 API 调用。

实际上这里的返回类型不是anything,而是严格依赖于items数组中的对象类型。

无论如何我可以为这个方法的使用者提供一个返回类型吗?

class Group<T> {
  items: Array<T> = [];

  addItem(item: T) {
      this.items.push(item);
  }

  getData(itemIndex: number) {
    // Any is T
    return (this.items[itemIndex] as any).data;
  }
}

class NumberItem {
  data: number;

  constructor(data: number) {
      this.data = data;
  }
}

class StringItem {
  data: String = "";

  constructor(data: String) {
      this.data = data;
  }
}

let n1 = new NumberItem(3);
let n2 = new NumberItem(4);

let g1 = new Group<NumberItem>();
g1.addItem(n1);
g1.addItem(n2);

console.log(g1.getData(1));

Playground Link

【问题讨论】:

  • 您如何期望它能够从泛型类型中的属性推断类型?您应该使用unknown,但这已经足够了。
  • @MikeS。那是错的;看我的回答。
  • @kaya3 没错,但我措辞不正确。您无法从泛型内部的属性中知道类型,如果您不知道属性名称,您的解决方案可以工作,因为它依赖于 data 属性始终存在。巧妙的解决方案,但不知道你能做到这一点。
  • @MikeS。本题不涉及属性名未知的情况,但在那种情况下还是可能的;不需要上限,返回类型为T[keyof T]
  • 你说的很对,谢谢你的澄清

标签: typescript typescript-generics


【解决方案1】:

T 一个上限,使其具有data 属性,则返回类型为T['data']。这样,getData 方法中也不需要类型断言。

class Group<T extends { data: any }> {
  items: Array<T> = [];

  addItem(item: T) {
    this.items.push(item);
  }

  getData(itemIndex: number): T['data'] {
    return this.items[itemIndex].data;
  }
}

用法:

let n1 = new NumberItem(3);
let n2 = new NumberItem(4);

let g1 = new Group<NumberItem>();
g1.addItem(n1);
g1.addItem(n2);

// result: number
const result = g1.getData(1);

【讨论】:

  • 我已经更新了我的代码,仍然显示任何类型为typescriptlang.org/play?#code/…
  • @user11406 你没有添加返回类型注释: T['data']
  • 超级整洁!我不知道这是可能的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
相关资源
最近更新 更多