diff --git a/packages/@ember/-internals/utils/types.ts b/packages/@ember/-internals/utils/types.ts index fd72f5ebd52..0c759a1e037 100644 --- a/packages/@ember/-internals/utils/types.ts +++ b/packages/@ember/-internals/utils/types.ts @@ -1,10 +1,18 @@ export type AnyFn = (...args: any[]) => any; -export type MethodNamesOf = { - [K in keyof T]: T[K] extends AnyFn ? K : never; -}[keyof T]; +// The formatting here is designed to help make this type actually be +// comprehensible to mortals, including the mortals who came up with it. +// prettier-ignore +export type MethodsOf = { + // This `keyof` check is the thing which gives us *only* these keys, and no + // `foo: never` appears in the final type. + [K in keyof T as T[K] extends AnyFn ? K : never]: + // While this makes sure the resolved type only has `AnyFn` in it, so that + // the resulting type is known to be only function types. + T[K] extends AnyFn ? T[K] : never; +}; -export type MethodsOf = Pick>; +export type MethodNamesOf = keyof MethodsOf; export type MethodParams> = Parameters[M]>; diff --git a/types/preview/ember/-private/type-utils.d.ts b/types/preview/ember/-private/type-utils.d.ts index 08d63c48450..f47c00631f4 100644 --- a/types/preview/ember/-private/type-utils.d.ts +++ b/types/preview/ember/-private/type-utils.d.ts @@ -7,11 +7,19 @@ declare module 'ember/-private/type-utils' { export type AnyMethod = (this: Target, ...args: any[]) => unknown; - export type MethodNamesOf = { - [K in keyof O]: O[K] extends AnyFn ? K : never; - }[keyof O]; + // The formatting here is designed to help make this type actually be + // comprehensible to mortals, including the mortals who came up with it. + // prettier-ignore + export type MethodsOf = { + // This `keyof` check is the thing which gives us *only* these keys, and no + // `foo: never` appears in the final type. + [K in keyof T as T[K] extends AnyFn ? K : never]: + // While this makes sure the resolved type only has `AnyFn` in it, so that + // the resulting type is known to be only function types. + T[K] extends AnyFn ? T[K] : never; + }; - export type MethodsOf = Pick>; + export type MethodNamesOf = keyof MethodsOf; export type MethodParams> = Parameters[M]>; @@ -20,16 +28,15 @@ declare module 'ember/-private/type-utils' { // prettier-ignore /** Get the return value of a method string name or a function. */ export type EmberMethodParams> = - M extends AnyMethod ? Parameters : - M extends keyof T ? T[M] extends AnyMethod ? Parameters[M]> : never : - never; + // For a basic method, we can just use the direct accessor. + M extends AnyMethod ? Parameters : + M extends MethodNamesOf ? Parameters[M]> : never; // prettier-ignore /** Get the return value of a method string name or a function. */ export type EmberMethodReturn> = - M extends AnyMethod ? ReturnType : - M extends keyof T ? T[M] extends AnyMethod ? ReturnType[M]> : never : - never; + M extends AnyMethod ? ReturnType : + M extends MethodNamesOf ? ReturnType[M]> : never; /** * A type utility for Ember's common name-of-object-on-target-or-function