你如何输入一个功能性的mixin reducer?
How can you type a functional mixin reducer?
我正在学习打字稿,并且正在努力弄清楚如何正确地键入减少函数混合的缩减器函数。
给定两个功能混合,如:
type FooComposable = {
foo: string;
};
const withFoo = (composable): FooComposable => {
composable.foo = 'foo';
return composable;
};
type BarComposable = {
bar: string;
};
const withBar = (composable): BarComposable => {
composable.bar = 'bar';
return composable;
};
我有一个 reducer 函数,可以减少所有提供的功能混合:
const reduce(...fns) = fns.reduce((acc, fn) => fn(acc), {}));
reduce(withFoo); // -> { foo: 'foo' }
reduce(withBar); // -> { bar: 'bar' }
reduce(withFoo, withBar); // -> { foo: 'foo', bar: 'bar' }
如何将类型添加到 reduce()
函数(和函数混合),以便生成的简化可组合项具有预期的类型推断?
type FooComposable = {
foo: string;
};
const withFoo = <T extends FooComposable>(composable: T): FooComposable => {
composable.foo = 'foo';
return composable;
};
type BarComposable = {
bar: string;
};
const withBar = <T extends BarComposable>(composable: T): BarComposable => {
composable.bar = 'bar';
return composable;
};
type FunctionalMixin<T extends {}> = (composable: T) => T;
const reduce = <T extends {}>(...fns: FunctionalMixin<T>[]): T =>
fns.reduce((acc, fn) => fn(acc), {});
/* Type '{}' is not assignable to type 'T'.
'{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. */
reduce<FooComposable & BarComposable>(withFoo, withBar); // -> { foo: 'foo', bar: 'bar' }
/* Argument of type '<T extends FooComposable>(composable: T) => FooComposable' is not assignable to parameter of type 'FunctionalMixin<FooComposable & BarComposable>'.
Type 'FooComposable' is not assignable to type 'FooComposable & BarComposable'.
Property 'bar' is missing in type 'FooComposable' but required in type 'BarComposable'. */
How can I add typings to the reduce()
function (and functional mixins) such that a resultant reduced composable has expected type inferences?
在以下示例中,result
具有正确推断的类型 Foo & Bar
。
type Foo = {
foo: string;
};
const withFoo: Mixin<Foo> = (a) => ({ ...a, foo: 'foo' });
type Bar = {
bar: string;
};
const withBar: Mixin<Bar> = (a) => ({ ...a, bar: 'bar' });
type Mixin<B> = <A extends object>(a: A) => A & B;
type Reduce<A extends object, T extends unknown[]> =
T extends [] ? A :
T extends [Mixin<infer B>, ...infer C] ? Reduce<A & B, C> :
never;
const reduce = <T extends Mixin<unknown>[]>(...fns: T): Reduce<{}, T> =>
fns.reduce((a, fn) => fn(a), {}) as Reduce<{}, T>;
const result = reduce(withFoo, withBar);
我正在学习打字稿,并且正在努力弄清楚如何正确地键入减少函数混合的缩减器函数。
给定两个功能混合,如:
type FooComposable = {
foo: string;
};
const withFoo = (composable): FooComposable => {
composable.foo = 'foo';
return composable;
};
type BarComposable = {
bar: string;
};
const withBar = (composable): BarComposable => {
composable.bar = 'bar';
return composable;
};
我有一个 reducer 函数,可以减少所有提供的功能混合:
const reduce(...fns) = fns.reduce((acc, fn) => fn(acc), {}));
reduce(withFoo); // -> { foo: 'foo' }
reduce(withBar); // -> { bar: 'bar' }
reduce(withFoo, withBar); // -> { foo: 'foo', bar: 'bar' }
如何将类型添加到 reduce()
函数(和函数混合),以便生成的简化可组合项具有预期的类型推断?
type FooComposable = {
foo: string;
};
const withFoo = <T extends FooComposable>(composable: T): FooComposable => {
composable.foo = 'foo';
return composable;
};
type BarComposable = {
bar: string;
};
const withBar = <T extends BarComposable>(composable: T): BarComposable => {
composable.bar = 'bar';
return composable;
};
type FunctionalMixin<T extends {}> = (composable: T) => T;
const reduce = <T extends {}>(...fns: FunctionalMixin<T>[]): T =>
fns.reduce((acc, fn) => fn(acc), {});
/* Type '{}' is not assignable to type 'T'.
'{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. */
reduce<FooComposable & BarComposable>(withFoo, withBar); // -> { foo: 'foo', bar: 'bar' }
/* Argument of type '<T extends FooComposable>(composable: T) => FooComposable' is not assignable to parameter of type 'FunctionalMixin<FooComposable & BarComposable>'.
Type 'FooComposable' is not assignable to type 'FooComposable & BarComposable'.
Property 'bar' is missing in type 'FooComposable' but required in type 'BarComposable'. */
How can I add typings to the
reduce()
function (and functional mixins) such that a resultant reduced composable has expected type inferences?
在以下示例中,result
具有正确推断的类型 Foo & Bar
。
type Foo = {
foo: string;
};
const withFoo: Mixin<Foo> = (a) => ({ ...a, foo: 'foo' });
type Bar = {
bar: string;
};
const withBar: Mixin<Bar> = (a) => ({ ...a, bar: 'bar' });
type Mixin<B> = <A extends object>(a: A) => A & B;
type Reduce<A extends object, T extends unknown[]> =
T extends [] ? A :
T extends [Mixin<infer B>, ...infer C] ? Reduce<A & B, C> :
never;
const reduce = <T extends Mixin<unknown>[]>(...fns: T): Reduce<{}, T> =>
fns.reduce((a, fn) => fn(a), {}) as Reduce<{}, T>;
const result = reduce(withFoo, withBar);