Home > Enterprise >  Fix intellisense to provide correct completion list on sub property used within function overloads
Fix intellisense to provide correct completion list on sub property used within function overloads

Time:05-21

I am trying to create an overload to a generic function where the return type of a function is determined by the value of a property on the object provided as "props" to the function. The function has a required generic type which is used also in the return type though it has no affect on which return type is returned.

I cannot add another generic type because I'll either have to define it manually or if I set a default type and use it on the first parameter to be inferred by the given parameter, it won't actually infer from it and will simply use the default type - very annoying.

I've got close to solving it, but the only issue I have left is that the intellisense for the property value is not showing all the available values for that property and I was hoping someone with a tiny bit more knowledge of TypeScript could help me past this final hurdle.

I have a link to the typescript playground code here so that you can tinker about with it in it's simplest form.

Below is the code too:

const EventType = Symbol('eventType');

type Unsubscribe = () => void;
type AnyFunction<ReturnType = any> = (...args: any[]) => ReturnType;

interface SingleResultEventCreateProps {
  mode: 'passthrough';
}

interface ArrayResultEventCreateProps {
  mode?: 'concurrent' | 'in-turn';
}

type EventCreateProps = SingleResultEventCreateProps | ArrayResultEventCreateProps

type ArrayResultEventDelegate<FuncType extends AnyFunction = AnyFunction> = ((delegate: FuncType) => Unsubscribe) & { [EventType]: 'array'; };
type SingleResultEventDelegate<FuncType extends AnyFunction = AnyFunction> = ((delegate: FuncType) => Unsubscribe) & { [EventType]: 'single'; };
type EventDelegate<FuncType extends AnyFunction = AnyFunction> = ArrayResultEventDelegate<FuncType> | SingleResultEventDelegate<FuncType>;

function create<FuncType extends AnyFunction>(): ArrayResultEventDelegate<FuncType>;
function create<FuncType extends AnyFunction>(props: ArrayResultEventCreateProps): ArrayResultEventDelegate<FuncType>;
function create<FuncType extends AnyFunction>(props: SingleResultEventCreateProps): SingleResultEventDelegate<FuncType>;
function create<FuncType extends AnyFunction>(props: EventCreateProps = {}): EventDelegate<FuncType> {
  return null as unknown as EventDelegate<FuncType>;
}

// the below works perfectly...except that the intellisense for mode offers only concurrent or in-turn, it does not offer passthrough as an possible value of mode.
const a = create<()=>string>({ mode: 'passthrough' }); // typeof a === SingleResultEventDelegate <-- correct
const b = create<()=>string>({ mode: 'concurrent' }); // typeof b === ArrayResultEventDelegate <-- correct
const c = create<()=>string>({ mode: 'in-turn' }); // typeof c === ArrayResultEventDelegate <-- correct

/*
to replicate my issue, remove the passthrough text from the mode property above, so it looks like this:

const a = create<()=>string>({ mode: '' });

then make sure your cursor is between the two quotes above and press ctrl   space and you'll see it only offers concurrent and in-turn as options.

Is there any way to offer all three modes via intellisense and still get the right return types?
*/

CodePudding user response:

It looks like you've run into a missing feature of TypeScript, reported at microsoft/TypeScript#44183. TypeScript seems to choose just one of the overloads from which to show potential completions. You could give that issue a

  • Related