【问题标题】:Typescript generic that generates an interface of builder function types生成构建器函数类型接口的 Typescript 泛型
【发布时间】:2021-05-29 20:01:03
【问题描述】:

给定一个 Typescript 接口:

interface Product {
  url: URL;
  available: boolean;
  price: number;
}

我想创建一个给定接口可以输出构建器类型的泛型类型:

interface ProductSteps {
  url: (data: unknown) => URL;
  available: (data: unknown) => boolean;
  price: (data: unknown) => number;
}

我已尝试使用 Record 实用程序类型来生成 Builder:

type Steps<T> = Record<keyof T, (data: unknown) => T[keyof T]>
type ProductSteps = Steps<Product>;

这工作正常,但它导致允许 Product 的任何值类型作为返回类型:

type ProductSteps {
  url: (data: unknown) => URL | boolean | number;
  available: (data: unknown) => URL | boolean | number;
  price: (data: unknown) => URL | boolean | number;
}

关于如何将构建器函数的返回类型限制为它们在Product 中的相应类型的任何想法?

【问题讨论】:

  • 你不能只使用带有[ P in keyof T ] 的映射类型来建立键和值之间的关系吗?喜欢this
  • type Steps2&lt;T&gt; = { [ P in keyof T ] : (data: unknown) =&gt; T[P] }; 你的例子中的这个正是我所需要的:) 谢谢
  • 是的,每当您认为“对应”时会想到“映射” - 它会立即引导您找到解决方案 :)
  • 我会记住这一点,感谢您的建议 :) 你想发布一个答案让我接受吗?
  • 我们能比data: unknown做得更好吗?数据类型是某种已知类型,还是我们可以将其设为泛型上的另一个变量?扩展@Oleg 的游乐场:tsplay.dev/4WyDAm

标签: typescript interface mapped-types


【解决方案1】:

我们希望基于两个通用值创建一个mapped type:一个ObjectType,如Product,一个DataType,代表我们正在映射的数据。对于对象类型 ([P in keyof ObjectType]) 的每个键,对应的值类型是一个函数,它获取数据并将其映射到该键 ((data: DataType) =&gt; ObjectType[P]) 的对象值。

type Steps<ObjectType, DataType> = {
  [P in keyof ObjectType]: (data: DataType) => ObjectType[P]
};

用你的Product 和任意的SomeDataInterface 调用它,如下所示:

type Test = Steps<Product, SomeDataInterface>;

解决:

type Test = {
    url: (data: SomeDataInterface) => URL;
    available: (data: SomeDataInterface) => boolean;
    price: (data: SomeDataInterface) => number;
}

Typescript Playground Link

【讨论】:

    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 2018-07-03
    • 2020-07-31
    • 2021-07-04
    相关资源
    最近更新 更多