Closed
Description
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);