gpt4 book ai didi

typescript - TypeScript 中由泛型类型组成的对象(类型递归)

转载 作者:行者123 更新时间:2023-12-04 07:43:37 24 4
gpt4 key购买 nike

给定以下无类型 TS:

const compose = (thunk: any): any => {
const res = { ...thunk() };
return { ...res, then: (f: any): any => compose(() => ({...res, ...f()})) };
};

我们可以用它来制作可组合的对象:
const { foo, bar } = compose(() => ({foo: 1})).then(() => ({bar: 2}))
// foo: 1, bar: 2
但是在 TS 中输入这个似乎很棘手,因为类型是递归的。
我能想到的最好的方法是:
type Compose<T> = (thunk: () => T) => T & { then: Compose<any> };

const compose2 = <T extends {}>(thunk: () => T): ReturnType<Compose<T>> => {
const res = { ...thunk() };
return { ...res, then: (f) => compose2(() => ({ ...res, ...f() })) };
};
这意味着所有掉出 compose2的对象属于 any 类型.
我想要完成的最终结果是使用所有组合对象键入的内容:
const combined = compose(() => ({foo: 1})).then(() => ({bar: 2}))
// type of combined: { foo: number } & { bar: number } & { then: … }
在我看来,我们需要某种 Fix可以打递归结的类型,如 then的类型在 Compose需要递归。
当然,如果我们反转 compose 的签名,可能有办法做到这一点。并以某种方式使用了 CPS。我愿意接受建议!
请注意,一个 2 元 compose ,姑且称之为 combine ,没有问题:
const combine = <A extends {}, B extends {}>(a: () => A, b: () => B): A & B => ({...a(), ...b()});
const bar = combine(() => ({foo: 1}), () => combine(() => ({bar: 2}), () => ({baz: 3})) )
但是编写语句并不是特别好,所以我希望从结果对象传递一个闭包,这样我就不必嵌套重复的函数调用。

最佳答案

我想你可能正在寻找这个:

type Compose<O extends object = {}> =
<T extends object>(thunk: () => T) => T & O & {
then: Compose<T & O>
}

const compose: Compose = (thunk) => {
const res = { ...thunk() };
return { ...res, then: f => compose(() => ({ ...res, ...f() })) };
};
then()的返回类型携带一些您需要在撰写类型中表示的状态信息。如果我们想到 O作为“当前状态对象”,然后 Compose<O>是一个通用函数,它采用 thunk类型 () => T对于任何其他对象类型 T ,并返回 T & O & {then: Compose<T & O>} ...也就是说,新对象是 T的交集和 O ,及其 then()方法有 T & O作为新的状态。
事实执行 compose()类型检查是一个好兆头。让我们验证编译器是否理解调用的工作方式:
const { foo, bar } = compose(() => ({ foo: 1 })).then(() => ({ bar: "hello" }));

console.log(foo.toFixed(2)) // 1.00
console.log(bar.toUpperCase()); // HELLO
看起来挺好的!
Playground link to code

关于typescript - TypeScript 中由泛型类型组成的对象(类型递归),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67318316/

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