Creating a function type that returns argument object with possible extra props

466 Views Asked by At

I'm looking to create a function flowLens that takes an array of functions with a special signature / type.

  • The function can only have one argument
  • The function's arg should be a plain-object
  • The function must return all the same keys / value types in the plain-object
  • The function can return extra / new properties.

Here was my attempt:

type Plain = {[key: string]: any};
type SpecialFunction = <T extends Plain, R extends T & Plain>(props: T) => R;
    
function flowLens (...fns: SpecialFunction[]) {}

const invalidType = (props: { a: number }) => true;
const invalidNotArgs = (props: { a: number }) => ({ ducks: 1 });
const validOne = (props: { a: number }) => ({...props});
const validTwo = (props: { a: number }) => ({ ...props, b: 1 });

flowLens(invalidType)
flowLens(invalidNotArgs)
flowLens(validOne)
flowLens(validTwo)

Playground

Is it possible to do this? If so how?

1

There are 1 best solutions below

0
On

For types to be validated when calling flowLens, you'll need to move the generics to parameterize SpecialFunction directly. The following should work:

type SpecialFunction<T extends Record<string, any>> = (props: T) => T;

function flowLens<T extends any[]>(...fns: {[K in keyof T]: SpecialFunction<T[K]>}) {}

TypeScript allows extraneous properties by default, so you shouldn't need any additional handling to allow those on the return type.