我如何才能强烈地键入合成的混合成分? [英] How can I strongly type a composed mixin?
本文介绍了我如何才能强烈地键入合成的混合成分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用函数组合将行为添加到具有Mixin的对象:
const pipe = (...funcs: ((...args: any[]) => any)[]) => (initial: any) => funcs.reduce((object, fn) => fn(object), initial);
const speakMixin = <T,>(obj: T): T & { speak: () => void } => ({
...obj,
speak: () => console.log("I can speak!")
});
const flyMixin = <T,>(obj: T): T & { fly: () => void } => ({
...obj,
fly: () => console.log("i'm flying")
});
const chain = pipe(speakMixin, flyMixin);
const mixed = chain({});
mixed.fly(); // fly member is typed to any
有没有更好的方法来键入我的pipe
函数,以便我在已应用混合的对象上获得类型安全?
推荐答案
深入研究这个问题我已经意识到,我以前键入的compose/pipeline
函数在这种情况下没有帮助。
如果你有一套这样的函数,我想你可以这样输入:
type Fn = (arg: any) => any
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
const pipe =
<T extends Fn, Fns extends T[]>(...fns: [...Fns]) =>
<Data extends Record<string, unknown>>(data: Data) =>
fns.reduce((acc, fn) => fn(acc), data) as Data & UnionToIntersection<ReturnType<Fns[number]>>;
const speakMixin = <T,>(obj: T) => ({
...obj,
speak: () => console.log("I can speak!")
});
const flyMixin = <T,>(obj: T) => ({
...obj,
fly: () => console.log("i'm flying")
});
// const check: {
// age: number;
// } & {
// fly: () => void;
// } & {
// speak: () => void;
// }
const check = pipe(flyMixin, speakMixin)({ age: 42 })
相关问题列表:[typing pipe function,typing pipe function 2,typing compose function,my article]
这篇关于我如何才能强烈地键入合成的混合成分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文