Skip to content

Commit

Permalink
Try making createInstance typings more strict
Browse files Browse the repository at this point in the history
For #81574

`IInstantiationService.createInstance` currently does not do a good job at making sure you don't pass `undefined` as a parameter (see #81574)

This change attempt to fix that by making the typings more explicit. The fix in turn revealed a lot of places where possible type errors were slipping through
  • Loading branch information
mjbvz committed Oct 4, 2019
1 parent 831800d commit ce3b2dc
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions src/vs/platform/instantiation/common/instantiation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ export interface ServicesAccessor {

export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');

/**
* Given a list of arguments as a tuple, attempt to extract the leading, non-service arguments
* to their own tuple.
*/
type GetLeadingNonServiceArgs<Args> =
Args extends [...BrandedService[]] ? []
: Args extends [infer A1, ...BrandedService[]] ? [A1]
: Args extends [infer A1, infer A2, ...BrandedService[]] ? [A1, A2]
: Args extends [infer A1, infer A2, infer A3, ...BrandedService[]] ? [A1, A2, A3]
: Args extends [infer A1, infer A2, infer A3, infer A4, ...BrandedService[]] ? [A1, A2, A3, A4]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, ...BrandedService[]] ? [A1, A2, A3, A4, A5]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6, A7]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6, A7, A8]
: never;

export interface IInstantiationService {

_serviceBrand: undefined;
Expand All @@ -85,15 +101,7 @@ export interface IInstantiationService {
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(descriptor: descriptors.SyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(descriptor: descriptors.SyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): T;

createInstance<T>(ctor: IConstructorSignature0<T>): T;
createInstance<A1, T>(ctor: IConstructorSignature1<A1, T>, first: A1): T;
createInstance<A1, A2, T>(ctor: IConstructorSignature2<A1, A2, T>, first: A1, second: A2): T;
createInstance<A1, A2, A3, T>(ctor: IConstructorSignature3<A1, A2, A3, T>, first: A1, second: A2, third: A3): T;
createInstance<A1, A2, A3, A4, T>(ctor: IConstructorSignature4<A1, A2, A3, A4, T>, first: A1, second: A2, third: A3, fourth: A4): T;
createInstance<A1, A2, A3, A4, A5, T>(ctor: IConstructorSignature5<A1, A2, A3, A4, A5, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): T;
createInstance<A1, A2, A3, A4, A5, A6, T>(ctor: IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(ctor: IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): T;
createInstance<Ctor extends new (...args: any) => any, Args extends GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>>(t: Ctor, ...args: Args): InstanceType<Ctor>;

/**
*
Expand Down

0 comments on commit ce3b2dc

Please sign in to comment.