grafast
Version:
Cutting edge GraphQL planning and execution engine
50 lines • 2.14 kB
TypeScript
import type { Step } from "../step.js";
/**
* If your step class has a `get` method you should implement this so users
* benefit from type safety.
*
* e.g.
* ```ts
* class MyStep extends Step {
* __inferGet?: {
* [TKey in keyof MyData]: MySpecialStep<MyData[TKey]>;
* };
* get<TKey extends keyof MyData>(key: TKey): MySpecialStep<MyData[TKey]> {
* // ...
* }
* }
* ```
*/
interface HasInferredGet<TStepByKey extends Record<string, Step>> {
/**
* TypeScript hack so we can infer the type of getting each key; this key
* won't actually have a value
*/
__inferGet?: TStepByKey;
}
/**
* Determines the keys that a given step represents
*
* 1. If it implements HasInferredGet, get the explicit keys
* 2. Otherwise, if it has a get method, figure out which attributes it accepts
* 3. Otherwise, determine the type the Step encodes and extract the keys of that
*/
type StepGetKeys<TStep extends Step> = TStep extends HasInferredGet<infer UStepByKey> ? keyof UStepByKey : TStep extends {
get(attr: infer U): any;
} ? U : TStep extends Step<infer UData | null | undefined> ? keyof UData : never;
/**
* Determines the type of the step returned from `get(step, attr)`.
*
* 1. If it implements HasInferredGet, get a step representing that specific attribute
* 2. Otherwise, if it has a get method, return the ReturnType of that method
* 3. Otherwise, determine the type the Step encodes and return a Step representing the relevant key of that
*/
type GetResult<TStep extends Step, TAttr extends StepGetKeys<TStep>> = TStep extends HasInferredGet<infer UStepByKey> ? TAttr extends keyof UStepByKey ? UStepByKey[TAttr] : never : TStep extends {
get(attr: any): infer UGetStep;
} ? UGetStep : TStep extends Step<infer UData | null | undefined> ? TAttr extends keyof UData ? Step<UData[TAttr]> : never : never;
/**
* Call `$step.get(attr)` if possible, falling back to `access($step, attr)`.
*/
export declare function get<TStep extends Step, TAttr extends StepGetKeys<TStep> & string>($step: TStep, attr: TAttr): GetResult<TStep, TAttr>;
export {};
//# sourceMappingURL=get.d.ts.map