Skip to content

Commit

Permalink
Merge pull request #29705 from Microsoft/fixParametersAndReturnType
Browse files Browse the repository at this point in the history
Less restrictive Parameters<T> and ReturnType<T>
  • Loading branch information
ahejlsberg authored Feb 4, 2019
2 parents 530a09a + 118a2cc commit f86b635
Show file tree
Hide file tree
Showing 9 changed files with 523 additions and 494 deletions.
8 changes: 4 additions & 4 deletions src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1451,22 +1451,22 @@ type NonNullable<T> = T extends null | undefined ? never : T;
/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

/**
* Marker for contextual 'this' type
Expand Down
24 changes: 5 additions & 19 deletions tests/baselines/reference/genericRestParameters1.errors.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more.
tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more.
tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'.
Types of parameters 'args' and 'args' are incompatible.
Type 'any[]' is not assignable to type 'T'.
tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'.
Types of parameters 'args' and 'args' are incompatible.
Type 'any[]' is not assignable to type 'T'.
tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'.
Type 'Function' provides no match for the signature '(...args: any[]): any'.
tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'.
Type 'Function' provides no match for the signature '(...args: any): any'.
tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'.
Types of parameters 'a' and 'args' are incompatible.
Type 'any' is not assignable to type 'never'.


==== tests/cases/conformance/types/rest/genericRestParameters1.ts (6 errors) ====
==== tests/cases/conformance/types/rest/genericRestParameters1.ts (4 errors) ====
declare let f1: (...x: [number, string, boolean]) => void;
declare let f2: (x0: number, x1: string, x2: boolean) => void;

Expand Down Expand Up @@ -152,19 +146,11 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232
type T05<T> = Parameters<(...args: T[]) => void>;
type T06<T> = ConstructorParameters<new (...args: []) => void>;
type T07<T extends any[]> = Parameters<(...args: T) => void>;
~~~~~~~~~~~~~~~~~~~~
!!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'.
!!! error TS2344: Types of parameters 'args' and 'args' are incompatible.
!!! error TS2344: Type 'any[]' is not assignable to type 'T'.
type T08<T extends any[]> = ConstructorParameters<new (...args: T) => void>;
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'.
!!! error TS2344: Types of parameters 'args' and 'args' are incompatible.
!!! error TS2344: Type 'any[]' is not assignable to type 'T'.
type T09 = Parameters<Function>;
~~~~~~~~
!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any[]): any'.
!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any): any'.

type Record1 = {
move: [number, 'left' | 'right'];
Expand Down
89 changes: 0 additions & 89 deletions tests/baselines/reference/genericRestParameters2.errors.txt

This file was deleted.

59 changes: 35 additions & 24 deletions tests/baselines/reference/inferTypes1.errors.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any[]) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'.
Type 'Function' provides no match for the signature '(...args: any[]): any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(37,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any[]) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any[]) => any'.
Type 'Function' provides no match for the signature 'new (...args: any[]): any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(46,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'.
Type 'Function' provides no match for the signature '(...args: any): any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(39,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'.
Type 'Function' provides no match for the signature 'new (...args: any): any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(48,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'.
Type 'Function' provides no match for the signature '(x: any): any'.
tests/cases/conformance/types/conditional/inferTypes1.ts(73,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(74,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(74,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(74,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS2304: Cannot find name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: Cannot find name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(82,44): error TS2344: Type 'U' does not satisfy the constraint 'string'.
tests/cases/conformance/types/conditional/inferTypes1.ts(74,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(75,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS2304: Cannot find name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS2304: Cannot find name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
tests/cases/conformance/types/conditional/inferTypes1.ts(83,44): error TS2344: Type 'U' does not satisfy the constraint 'string'.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'.
tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'.
Type 'T' is not assignable to type 'symbol'.


Expand Down Expand Up @@ -54,22 +54,23 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322:
type T16 = ReturnType<never>; // never
type T17 = ReturnType<string>; // Error
~~~~~~
!!! error TS2344: Type 'string' does not satisfy the constraint '(...args: any[]) => any'.
!!! error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'.
type T18 = ReturnType<Function>; // Error
~~~~~~~~
!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any[]): any'.
!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any): any'.
type T19<T extends any[]> = ReturnType<(x: string, ...args: T) => T[]>; // T[]

type U10 = InstanceType<typeof C>; // C
type U11 = InstanceType<any>; // any
type U12 = InstanceType<never>; // never
type U13 = InstanceType<string>; // Error
~~~~~~
!!! error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any[]) => any'.
!!! error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'.
type U14 = InstanceType<Function>; // Error
~~~~~~~~
!!! error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any[]) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature 'new (...args: any[]): any'.
!!! error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'.
!!! error TS2344: Type 'Function' provides no match for the signature 'new (...args: any): any'.

type ArgumentType<T extends (x: any) => any> = T extends (a: infer A) => any ? A : any;

Expand Down Expand Up @@ -226,4 +227,14 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322:

type Test1 = EnsureIsString<"hello">; // "hello"
type Test2 = EnsureIsString<42>; // never

// Repros from #26856

function invoker <K extends string | number | symbol, A extends any[]> (key: K, ...args: A) {
return <T extends Record<K, (...args: A) => any>> (obj: T): ReturnType<T[K]> => obj[key](...args)
}

const result = invoker('test', true)({ test: (a: boolean) => 123 })

type Foo2<A extends any[]> = ReturnType<(...args: A) => string>;

20 changes: 20 additions & 0 deletions tests/baselines/reference/inferTypes1.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type T15 = ReturnType<any>; // any
type T16 = ReturnType<never>; // never
type T17 = ReturnType<string>; // Error
type T18 = ReturnType<Function>; // Error
type T19<T extends any[]> = ReturnType<(x: string, ...args: T) => T[]>; // T[]

type U10 = InstanceType<typeof C>; // C
type U11 = InstanceType<any>; // any
Expand Down Expand Up @@ -166,6 +167,16 @@ type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;

type Test1 = EnsureIsString<"hello">; // "hello"
type Test2 = EnsureIsString<42>; // never

// Repros from #26856

function invoker <K extends string | number | symbol, A extends any[]> (key: K, ...args: A) {
return <T extends Record<K, (...args: A) => any>> (obj: T): ReturnType<T[K]> => obj[key](...args)
}

const result = invoker('test', true)({ test: (a: boolean) => 123 })

type Foo2<A extends any[]> = ReturnType<(...args: A) => string>;


//// [inferTypes1.js]
Expand All @@ -182,3 +193,12 @@ var C = /** @class */ (function () {
}());
var z1 = ex.customClass;
var z2 = ex.obj.nested.attr;
// Repros from #26856
function invoker(key) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return function (obj) { return obj[key].apply(obj, args); };
}
var result = invoker('test', true)({ test: function (a) { return 123; } });
Loading

0 comments on commit f86b635

Please sign in to comment.