gpt4 book ai didi

TypeScript Generic Factory Function Type,匹配数组元素顺序

转载 作者:行者123 更新时间:2023-12-03 16:01:48 26 4
gpt4 key购买 nike

我想 build 某种 FactoryFactory : 基本上是一个返回工厂函数的通用函数。编写函数本身很简单,但我不知道如何为它做 TypeScript 类型。
该函数应该像这样使用:

const stubFactoryFunction = (...props) => (...values) => ({ /* ... */ });

const factory = stubFactoryFunction("prop1", "prop2");
const instance = factory("foo", 42);
console.log(instance); // { prop1: "foo", prop2: 42 }
起初,我尝试将值类型作为数组提供:
type FactoryFunction<T extends any[]> =
<K extends string[]>(...props: K) =>
(...values: T[number]) =>
{[key in K[number]]: T[number]}
但这将导致 { prop1: string | number, prop2: string | number} ,因为类型与数组索引不匹配。
接下来,我尝试将整个对象提供为泛型类型:
type FactoryFunction<T extends {[key: string]: any}> =
(...props: (keyof T)[]) =>
(...values: ???) =>
T
在这里我遇到了类似的问题: values必须以某种方式匹配 props 的顺序.
这可能吗?
奖金1:不允许重复 Prop 。
奖励 2:强制提供来自 T 的所有非可选 Prop .

最佳答案

我不知道以通用方式是否可行,因为映射类型可以映射值,而不是输入对象的键,这在这里是必需的。
有限数量参数的解决方案,这里从 1 到 3:

type MonoRecord<P, V> = P extends string ? Record<P, V> : never;

type Prettify<T> = T extends infer Tbis ? { [K in keyof Tbis]: Tbis[K] } : never;

type FactoryFunctionResult<
P extends (string[] & { length: 1|2|3 }),
V extends (any[] & { length: P['length'] })
> =
P extends [infer P0] ?
MonoRecord<P0, V[0]> :
P extends [infer P0, infer P1] ?
Prettify<
MonoRecord<P0, V[0]> &
MonoRecord<P1, V[1]>> :
P extends [infer P0, infer P1, infer P2] ?
Prettify<
MonoRecord<P0, V[0]> &
MonoRecord<P1, V[1]> &
MonoRecord<P2, V[2]>> :
never;

type FactoryFunctionTest1 = FactoryFunctionResult<['a'], [string]>; // { a: string }
type FactoryFunctionTest2 = FactoryFunctionResult<['a', 'b'], [string, number]>; // { a: string; b: number }
type FactoryFunctionTest3 = FactoryFunctionResult<['a', 'b', 'c'], [string, number, boolean]>; // { a: string; b: number; c: boolean }

const stubFactoryFunction = <P extends (string[] & { length: 1|2|3 })>(...props: P) =>
<V extends (any[] & { length: P['length'] })>(...values: V) =>
({ /* ... */ } as FactoryFunctionResult<P, V>);
一些解释:
  • 由于 & { length: 1|2|3 },参数数量限制为 3 个约束。
  • 由于 values,内部工厂必须具有与外部工厂参数 ( props ) 相同数量的参数 ( & { length: P['length'] } ) .
  • MonoRecord<P, V>FactoryFunctionResult 中很有用确保每个P0 .. P2扩展 string否则我们会得到一个 TS 错误。除此之外,它只是具有一个属性的对象的别名。例如。 MonoRecord<'a', number>{ a: number } .
  • Prettify<T>实用程序类型可用于美化交叉点类型。例如。 Prettify<{ a: number } & { b: string }>{ a: number; b: string } .

  • 最多有 4 个参数:
  • 更改约束 length: 1|2|3|4
  • FactoryFunctionResult 中添加第四个案例公式:
  •   P extends [infer P0, infer P1, infer P2, infer P3] ?
    Prettify<
    MonoRecord<P0, V[0]> &
    MonoRecord<P1, V[1]> &
    MonoRecord<P2, V[2]> &
    MonoRecord<P3, V[3]>> :

    关于TypeScript Generic Factory Function Type,匹配数组元素顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63341013/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com