如何在类型内创建“临时”类型,以保持 DRY?

gre*_*emo 6 typescript

我什至不知道如何在 SO 中搜索这个问题。我的通用类型FetchOptions实际上是这样的:

type FetchOptions<T> = {
  explode?: string & keyof T | (string & keyof T)[];
}
Run Code Online (Sandbox Code Playgroud)

我找不到创建另一种类型的方法string & keyof T,以避免在后续数组定义中重复并且不提取类型(在类型本身内部):

type Key<T> = string & keyof T;

type Options<T> = {
  explode?: Key<T> | Key<T>[];
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

class Product {
  id: number | string;
  name: string;
  variants?: ProductVariant[];
  attributes?: ProductVariant[];
}

const fetchProducts = (options: FetchOptions<Product> = {}) => {
  // ...
};

fetchProducts({ explode: 'variants' });
fetchProducts({ explode: ['variants', 'attributes'] });
Run Code Online (Sandbox Code Playgroud)

Tob*_* S. 5

我经常看到带有默认值的附加通用参数,用于避免重复。

type FetchOptions<T, E = string & keyof T> = {
  explode?: E | E[];
}
Run Code Online (Sandbox Code Playgroud)

当像这样使用时FetchOptions<Product>,您会得到与以前相同的行为。但您可能需要担心意外提供第二个通用参数。E不是约束,因此任何类型都可以传递给FetchOptions.

我们可以添加一个约束来保证正确的类型。

type FetchOptions<T, E extends string & keyof T = string & keyof T> = {
  explode?: E | E[];
}
Run Code Online (Sandbox Code Playgroud)

但是,由于这使我们两次键入该类型,因此它可能只有在更频繁地使用该类型时才有用。


操场