Skip to content

infer the spread operator function parameter names and types, via generic type extraction #25634

Closed
@wesleyolis

Description

@wesleyolis

I would like the ability to be able to re-write and wrap code correctly for promises and similar things,
with out having to have a whole bunch of intermediate statements function calls, when could be done in one statement, but then I need the typing system to support the ability to be able to do that.

Their are 3 Features in this request, in priority order, were we can polyfill the rest with copy and past in the mean time.

  • infer the parameters for a spread operator.
  • Extract existing function parameter names and types with defaults
  • Conditional Generic extends constraint.
  • check the position of key in keyof (minor)

Extract Parameter Names And Types from a function

function MyFunc(a : string, b : boolean, ...args: A[]){}

type ExtractParamsNames<T extends Function> = 
{
	[K in keyof T] : K
}	

type funParamNames = ExtractParamsNames<typeof MyFunc>
// Exepect the following:
// a
// b
// ..args


type ExtractParamsTypes<T extends Function> = 
{
	[K in keyof T] : T[K]
}	

type funParamValues = ExtractParamsTypes<typeof MyFunc>
// Expect the following:
// string
// boolean
// A

type ExtractParamDefault<T extends Param> T extends {type: any, default : infer R} ? R : undefined

Conditional Generic extends constraint.

function fun<O extends {}, 
M extends keyof O ? keyof O :  O extends (A: infer, ..args: any []) => void ? A : undefined,
S extends O extends keyof O ? ExtractParms<O[M]> : DropPram<Extract<Params>>(paramA : O, paramB : M, args : S) : void

fun(object, 'key', EParamA, EParamB, EParamC); // this would be the typical way of doing tings.
fun(object.key,EParamA, EParamB, EParamC); // this  is why we need it, so I can drop a spread parameters and have the PropB become the first spread operator extracted parameter.

Extract types based on a key position

ExtractParamsWithPos<T extends Function> =
{
	[K in keyof T] : K extends T.Length ? {param: K, type: T[K]} : never
}

Infer the parameters of the spread operator

type CallBackType<T> =  (err: any, result:  T) => void

// Drop the call back function signature if found,
// need a way to determine if this is the last parameer as well.
ExtractParamsAndTypes<T extends Function> =
{
	[K in keyof T] : T[K] extends CallBackType ? never : {param: K, type: T[K]}
}


ExtractParamsAndTypesWithPos<T extends Function> =
{
	[K in keyof T] : K extends T.Length ? T[K] extends CallBackType ? never : {param: K, type: T[K]} : never
}

// like to be able to extract a functions types, using generics.
// the infer the current spread operate arguments, like in the following.

function Promisifiy<R, O, M extends keyof O | underfined,
A = ExtractParamsAndTypes<M extends undefined ? O : O[M]>
(obejct: O, keyMethod : M, ... args : A)
: R extends undefined ? ExtractBlueBirdCallbackResults<O[M]> : BlueBird<R> 
{
	if (propB === undefined)
			return Bluebird.promisify(propA)(args);
		else if (propA[propB])
			return Bluebird.promisify(propA[propB], {context: propA})(args);
// execute the statment, save me having to have intermediate step, 
// that is require to new the promise, can do all this in one line.
}


const lib = {
	myMethod : function (paramA : string, paramB : number, paramC : boolean, callback : CallBackType<Actually> ): void
}

Resulting use cases

Case A , when function signature is conventional/compliant for the types definitions.

interface Actually
{
	resultA : string,
	restultB  : number
}


const myMethodPromise = Promisify(lib, 'myMethod', 'paramA', 'paramB',' 'ParamC');
myMethodPromise.then(r => r.resultsA || r.resultsB);

Case B, Overide the return type

interface Overide
{
	OverideA : string,
	OverideB  : number
}

const myMethodPromiseOverideResult = Promisify<Overide>(lib, 'myMethod', 'paramA', 'paramB',' 'ParamC');
myMethodPromiseOverideResult.then(r => r.OverideA || r.OverideB);

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions