mirror of
https://github.com/zhigang1992/DefinitelyTyped.git
synced 2026-06-01 11:39:28 +08:00
[ember] refine types for Ember.tryInvoke (#28693)
* [ember] refine types for Ember.tryInvoke * [ember] tryInvoke as three function heads
This commit is contained in:
committed by
Ryan Cavanaugh
parent
2a2f49e0d0
commit
59f25426d5
23
types/ember/index.d.ts
vendored
23
types/ember/index.d.ts
vendored
@@ -28,6 +28,20 @@ declare module 'ember' {
|
||||
// Get an alias to the global Array type to use in inner scope below.
|
||||
type GlobalArray<T> = T[];
|
||||
|
||||
// TODO: TypeScript 3.0
|
||||
// type FunctionArgs<F extends (...args: any[]) => any> = F extends (...args: infer ARGS) => any ? ARGS : never;
|
||||
type FunctionArgs<F> =
|
||||
F extends (a: infer A) => any
|
||||
? [A]
|
||||
: F extends (a: infer A, b: infer B) => any
|
||||
? [A, B]
|
||||
: F extends (a: infer A, b: infer B, c: infer C) => any
|
||||
? [A, B, C]
|
||||
: F extends (a: infer A, b: infer B, c: infer C, d: infer D) => any
|
||||
? [A, B, C, D]
|
||||
: F extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E) => any
|
||||
? [A, B, C, D, E]
|
||||
: never;
|
||||
/**
|
||||
* Deconstructs computed properties into the types which would be returned by `.get()`.
|
||||
*/
|
||||
@@ -3320,7 +3334,14 @@ declare module 'ember' {
|
||||
* Checks to see if the `methodName` exists on the `obj`,
|
||||
* and if it does, invokes it with the arguments passed.
|
||||
*/
|
||||
function tryInvoke(obj: any, methodName: string, args?: any[]): any;
|
||||
function tryInvoke<FNAME extends keyof T, T extends object>(
|
||||
obj: T,
|
||||
methodName: FNAME,
|
||||
args: FunctionArgs<T[FNAME]>): T[FNAME] extends ((...args: any[]) => any)
|
||||
? ReturnType<T[FNAME]>
|
||||
: undefined;
|
||||
function tryInvoke<FNAME extends keyof T, T extends object>(obj: T, methodName: FNAME): T[FNAME] extends (() => any) ? ReturnType<T[FNAME]> : undefined;
|
||||
function tryInvoke(obj: object, methodName: string, args?: any[]): undefined;
|
||||
/**
|
||||
* Forces the passed object to be part of an array. If the object is already
|
||||
* an array, it will return the object. Otherwise, it will add the object to
|
||||
|
||||
@@ -99,3 +99,31 @@ function testDefineProperty() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
}));
|
||||
}
|
||||
|
||||
function testTryInvoke() {
|
||||
class Foo {
|
||||
hello() { return ['world']; }
|
||||
add(x: number, y: string) { return x + parseInt(y, 10); }
|
||||
apples(n: number) { return `${n} apples`; }
|
||||
}
|
||||
// zero-argument function
|
||||
Ember.tryInvoke(new Foo(), 'hello'); // $ExpectType string[]
|
||||
// one-argument function
|
||||
Ember.tryInvoke(new Foo(), 'apples', [4]); // $ExpectType string
|
||||
// multi-argument function with different types (reversed types negative test case below)
|
||||
Ember.tryInvoke(new Foo(), 'add', [4, '3']); // $ExpectType number
|
||||
|
||||
// Cases that should return undefined
|
||||
// No args provided
|
||||
Ember.tryInvoke(new Foo(), 'apples'); // $ExpectType undefined
|
||||
// Function does not exist
|
||||
Ember.tryInvoke(new Foo(), 'doesNotExist'); // $ExpectType undefined
|
||||
// Empty args provided
|
||||
Ember.tryInvoke(new Foo(), 'apples', []); // $ExpectType undefined
|
||||
// Wrong args provided
|
||||
Ember.tryInvoke(new Foo(), 'apples', ['']); // $ExpectType undefined
|
||||
// Wrong arg types
|
||||
Ember.tryInvoke(new Foo(), 'add', [4, 3]); // $ExpectType undefined
|
||||
// Reversed arg types
|
||||
Ember.tryInvoke(new Foo(), 'add', ['4', 3]); // $ExpectType undefined
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user