Merge pull request #13358 from Microsoft/iifeMissingArguments

Infer optional types for IIFE parameters with missing arguments
This commit is contained in:
Anders Hejlsberg 2017-01-09 09:30:49 -10:00 committed by GitHub
commit ecb2115aeb
10 changed files with 609 additions and 1031 deletions

View file

@ -5058,9 +5058,10 @@ namespace ts {
if (!links.resolvedSignature) {
const parameters: Symbol[] = [];
let hasLiteralTypes = false;
let minArgumentCount = -1;
let minArgumentCount = 0;
let thisParameter: Symbol = undefined;
let hasThisParameter: boolean;
const iife = getImmediatelyInvokedFunctionExpression(declaration);
const isJSConstructSignature = isJSDocConstructSignature(declaration);
// If this is a JSDoc construct signature, then skip the first parameter in the
@ -5087,14 +5088,12 @@ namespace ts {
hasLiteralTypes = true;
}
if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
if (minArgumentCount < 0) {
minArgumentCount = i - (hasThisParameter ? 1 : 0);
}
}
else {
// If we see any required parameters, it means the prior ones were not in fact optional.
minArgumentCount = -1;
// Record a new minimum argument count if this is not an optional parameter
const isOptionalParameter = param.initializer || param.questionToken || param.dotDotDotToken ||
iife && parameters.length > iife.arguments.length && !param.type ||
isJSDocOptionalParameter(param);
if (!isOptionalParameter) {
minArgumentCount = parameters.length;
}
}
@ -5109,13 +5108,6 @@ namespace ts {
}
}
if (minArgumentCount < 0) {
minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0);
}
if (isJSConstructSignature) {
minArgumentCount--;
}
const classType = declaration.kind === SyntaxKind.Constructor ?
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
: undefined;
@ -10935,23 +10927,23 @@ namespace ts {
const func = parameter.parent;
if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
const iife = getImmediatelyInvokedFunctionExpression(func);
if (iife) {
if (iife && iife.arguments) {
const indexOfParameter = indexOf(func.parameters, parameter);
if (iife.arguments && indexOfParameter < iife.arguments.length) {
if (parameter.dotDotDotToken) {
const restTypes: Type[] = [];
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
}
return createArrayType(getUnionType(restTypes));
if (parameter.dotDotDotToken) {
const restTypes: Type[] = [];
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
}
const links = getNodeLinks(iife);
const cached = links.resolvedSignature;
links.resolvedSignature = anySignature;
const type = getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter]));
links.resolvedSignature = cached;
return type;
return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
}
const links = getNodeLinks(iife);
const cached = links.resolvedSignature;
links.resolvedSignature = anySignature;
const type = indexOfParameter < iife.arguments.length ?
getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
parameter.initializer ? undefined : undefinedWideningType;
links.resolvedSignature = cached;
return type;
}
const contextualSignature = getContextualSignature(func);
if (contextualSignature) {

View file

@ -28,6 +28,9 @@
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
// missing arguments
(function(x, undefined) { return x; })(42);
((x, y, z) => 42)();
//// [contextuallyTypedIife.js]
@ -102,3 +105,6 @@ let eleven = (o => o.a(11))({ a: function(n) { return n; } });
// contextually typed parameters.
var twelve = (function (f) { return f(12); })(function (i) { return i; });
var eleven = (function (o) { return o.a(11); })({ a: function (n) { return n; } });
// missing arguments
(function (x, undefined) { return x; })(42);
(function (x, y, z) { return 42; })();

View file

@ -119,3 +119,14 @@ let eleven = (o => o.a(11))({ a: function(n) { return n; } });
>n : Symbol(n, Decl(contextuallyTypedIife.ts, 28, 42))
>n : Symbol(n, Decl(contextuallyTypedIife.ts, 28, 42))
// missing arguments
(function(x, undefined) { return x; })(42);
>x : Symbol(x, Decl(contextuallyTypedIife.ts, 30, 10))
>undefined : Symbol(undefined, Decl(contextuallyTypedIife.ts, 30, 12))
>x : Symbol(x, Decl(contextuallyTypedIife.ts, 30, 10))
((x, y, z) => 42)();
>x : Symbol(x, Decl(contextuallyTypedIife.ts, 31, 2))
>y : Symbol(y, Decl(contextuallyTypedIife.ts, 31, 4))
>z : Symbol(z, Decl(contextuallyTypedIife.ts, 31, 7))

View file

@ -250,3 +250,22 @@ let eleven = (o => o.a(11))({ a: function(n) { return n; } });
>n : any
>n : any
// missing arguments
(function(x, undefined) { return x; })(42);
>(function(x, undefined) { return x; })(42) : number
>(function(x, undefined) { return x; }) : (x: number, undefined: any) => number
>function(x, undefined) { return x; } : (x: number, undefined: any) => number
>x : number
>undefined : any
>x : number
>42 : 42
((x, y, z) => 42)();
>((x, y, z) => 42)() : number
>((x, y, z) => 42) : (x: any, y: any, z: any) => number
>(x, y, z) => 42 : (x: any, y: any, z: any) => number
>x : any
>y : any
>z : any
>42 : 42

View file

@ -0,0 +1,110 @@
//// [contextuallyTypedIifeStrict.ts]
// arrow
(jake => { })("build");
// function expression
(function (cats) { })("lol");
// Lots of Irritating Superfluous Parentheses
(function (x) { } ("!"));
((((function (y) { }))))("-");
// multiple arguments
((a, b, c) => { })("foo", 101, false);
// default parameters
((m = 10) => m + 1)(12);
((n = 10) => n + 1)();
// optional parameters
((j?) => j + 1)(12);
((k?) => k + 1)();
((l, o?) => l + o)(12); // o should be any
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
((...noNumbers) => noNumbers.some(n => n > 0))();
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
// destructuring parameters (with defaults too!)
(({ q }) => q)({ q : 13 });
(({ p = 14 }) => p)({ p : 15 });
(({ r = 17 } = { r: 18 }) => r)({r : 19});
(({ u = 22 } = { u: 23 }) => u)();
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
// missing arguments
(function(x, undefined) { return x; })(42);
((x, y, z) => 42)();
//// [contextuallyTypedIifeStrict.js]
// arrow
(function (jake) { })("build");
// function expression
(function (cats) { })("lol");
// Lots of Irritating Superfluous Parentheses
(function (x) { }("!"));
((((function (y) { }))))("-");
// multiple arguments
(function (a, b, c) { })("foo", 101, false);
// default parameters
(function (m) {
if (m === void 0) { m = 10; }
return m + 1;
})(12);
(function (n) {
if (n === void 0) { n = 10; }
return n + 1;
})();
// optional parameters
(function (j) { return j + 1; })(12);
(function (k) { return k + 1; })();
(function (l, o) { return l + o; })(12); // o should be any
// rest parameters
(function () {
var numbers = [];
for (var _i = 0; _i < arguments.length; _i++) {
numbers[_i] = arguments[_i];
}
return numbers.every(function (n) { return n > 0; });
})(5, 6, 7);
(function () {
var mixed = [];
for (var _i = 0; _i < arguments.length; _i++) {
mixed[_i] = arguments[_i];
}
return mixed.every(function (n) { return !!n; });
})(5, 'oops', 'oh no');
(function () {
var noNumbers = [];
for (var _i = 0; _i < arguments.length; _i++) {
noNumbers[_i] = arguments[_i];
}
return noNumbers.some(function (n) { return n > 0; });
})();
(function (first) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
return first ? [] : rest.map(function (n) { return n > 0; });
})(8, 9, 10);
// destructuring parameters (with defaults too!)
(function (_a) {
var q = _a.q;
return q;
})({ q: 13 });
(function (_a) {
var _b = _a.p, p = _b === void 0 ? 14 : _b;
return p;
})({ p: 15 });
(function (_a) {
var _b = (_a === void 0 ? { r: 18 } : _a).r, r = _b === void 0 ? 17 : _b;
return r;
})({ r: 19 });
(function (_a) {
var _b = (_a === void 0 ? { u: 23 } : _a).u, u = _b === void 0 ? 22 : _b;
return u;
})();
// contextually typed parameters.
var twelve = (function (f) { return f(12); })(function (i) { return i; });
var eleven = (function (o) { return o.a(11); })({ a: function (n) { return n; } });
// missing arguments
(function (x, undefined) { return x; })(42);
(function (x, y, z) { return 42; })();

View file

@ -0,0 +1,132 @@
=== tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts ===
// arrow
(jake => { })("build");
>jake : Symbol(jake, Decl(contextuallyTypedIifeStrict.ts, 1, 1))
// function expression
(function (cats) { })("lol");
>cats : Symbol(cats, Decl(contextuallyTypedIifeStrict.ts, 3, 11))
// Lots of Irritating Superfluous Parentheses
(function (x) { } ("!"));
>x : Symbol(x, Decl(contextuallyTypedIifeStrict.ts, 5, 11))
((((function (y) { }))))("-");
>y : Symbol(y, Decl(contextuallyTypedIifeStrict.ts, 6, 14))
// multiple arguments
((a, b, c) => { })("foo", 101, false);
>a : Symbol(a, Decl(contextuallyTypedIifeStrict.ts, 8, 2))
>b : Symbol(b, Decl(contextuallyTypedIifeStrict.ts, 8, 4))
>c : Symbol(c, Decl(contextuallyTypedIifeStrict.ts, 8, 7))
// default parameters
((m = 10) => m + 1)(12);
>m : Symbol(m, Decl(contextuallyTypedIifeStrict.ts, 10, 2))
>m : Symbol(m, Decl(contextuallyTypedIifeStrict.ts, 10, 2))
((n = 10) => n + 1)();
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 11, 2))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 11, 2))
// optional parameters
((j?) => j + 1)(12);
>j : Symbol(j, Decl(contextuallyTypedIifeStrict.ts, 13, 2))
>j : Symbol(j, Decl(contextuallyTypedIifeStrict.ts, 13, 2))
((k?) => k + 1)();
>k : Symbol(k, Decl(contextuallyTypedIifeStrict.ts, 14, 2))
>k : Symbol(k, Decl(contextuallyTypedIifeStrict.ts, 14, 2))
((l, o?) => l + o)(12); // o should be any
>l : Symbol(l, Decl(contextuallyTypedIifeStrict.ts, 15, 2))
>o : Symbol(o, Decl(contextuallyTypedIifeStrict.ts, 15, 4))
>l : Symbol(l, Decl(contextuallyTypedIifeStrict.ts, 15, 2))
>o : Symbol(o, Decl(contextuallyTypedIifeStrict.ts, 15, 4))
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
>numbers : Symbol(numbers, Decl(contextuallyTypedIifeStrict.ts, 17, 2))
>numbers.every : Symbol(Array.every, Decl(lib.d.ts, --, --))
>numbers : Symbol(numbers, Decl(contextuallyTypedIifeStrict.ts, 17, 2))
>every : Symbol(Array.every, Decl(lib.d.ts, --, --))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 17, 31))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 17, 31))
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
>mixed : Symbol(mixed, Decl(contextuallyTypedIifeStrict.ts, 18, 2))
>mixed.every : Symbol(Array.every, Decl(lib.d.ts, --, --))
>mixed : Symbol(mixed, Decl(contextuallyTypedIifeStrict.ts, 18, 2))
>every : Symbol(Array.every, Decl(lib.d.ts, --, --))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 18, 27))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 18, 27))
((...noNumbers) => noNumbers.some(n => n > 0))();
>noNumbers : Symbol(noNumbers, Decl(contextuallyTypedIifeStrict.ts, 19, 2))
>noNumbers.some : Symbol(Array.some, Decl(lib.d.ts, --, --))
>noNumbers : Symbol(noNumbers, Decl(contextuallyTypedIifeStrict.ts, 19, 2))
>some : Symbol(Array.some, Decl(lib.d.ts, --, --))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 19, 34))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 19, 34))
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
>first : Symbol(first, Decl(contextuallyTypedIifeStrict.ts, 20, 2))
>rest : Symbol(rest, Decl(contextuallyTypedIifeStrict.ts, 20, 8))
>first : Symbol(first, Decl(contextuallyTypedIifeStrict.ts, 20, 2))
>rest.map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>rest : Symbol(rest, Decl(contextuallyTypedIifeStrict.ts, 20, 8))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 20, 43))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 20, 43))
// destructuring parameters (with defaults too!)
(({ q }) => q)({ q : 13 });
>q : Symbol(q, Decl(contextuallyTypedIifeStrict.ts, 22, 3))
>q : Symbol(q, Decl(contextuallyTypedIifeStrict.ts, 22, 3))
>q : Symbol(q, Decl(contextuallyTypedIifeStrict.ts, 22, 16))
(({ p = 14 }) => p)({ p : 15 });
>p : Symbol(p, Decl(contextuallyTypedIifeStrict.ts, 23, 3))
>p : Symbol(p, Decl(contextuallyTypedIifeStrict.ts, 23, 3))
>p : Symbol(p, Decl(contextuallyTypedIifeStrict.ts, 23, 21))
(({ r = 17 } = { r: 18 }) => r)({r : 19});
>r : Symbol(r, Decl(contextuallyTypedIifeStrict.ts, 24, 3))
>r : Symbol(r, Decl(contextuallyTypedIifeStrict.ts, 24, 16))
>r : Symbol(r, Decl(contextuallyTypedIifeStrict.ts, 24, 3))
>r : Symbol(r, Decl(contextuallyTypedIifeStrict.ts, 24, 33))
(({ u = 22 } = { u: 23 }) => u)();
>u : Symbol(u, Decl(contextuallyTypedIifeStrict.ts, 25, 3))
>u : Symbol(u, Decl(contextuallyTypedIifeStrict.ts, 25, 16))
>u : Symbol(u, Decl(contextuallyTypedIifeStrict.ts, 25, 3))
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
>twelve : Symbol(twelve, Decl(contextuallyTypedIifeStrict.ts, 27, 3))
>f : Symbol(f, Decl(contextuallyTypedIifeStrict.ts, 27, 14))
>f : Symbol(f, Decl(contextuallyTypedIifeStrict.ts, 27, 14))
>i : Symbol(i, Decl(contextuallyTypedIifeStrict.ts, 27, 26))
>i : Symbol(i, Decl(contextuallyTypedIifeStrict.ts, 27, 26))
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
>eleven : Symbol(eleven, Decl(contextuallyTypedIifeStrict.ts, 28, 3))
>o : Symbol(o, Decl(contextuallyTypedIifeStrict.ts, 28, 14))
>o.a : Symbol(a, Decl(contextuallyTypedIifeStrict.ts, 28, 29))
>o : Symbol(o, Decl(contextuallyTypedIifeStrict.ts, 28, 14))
>a : Symbol(a, Decl(contextuallyTypedIifeStrict.ts, 28, 29))
>a : Symbol(a, Decl(contextuallyTypedIifeStrict.ts, 28, 29))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 28, 42))
>n : Symbol(n, Decl(contextuallyTypedIifeStrict.ts, 28, 42))
// missing arguments
(function(x, undefined) { return x; })(42);
>x : Symbol(x, Decl(contextuallyTypedIifeStrict.ts, 30, 10))
>undefined : Symbol(undefined, Decl(contextuallyTypedIifeStrict.ts, 30, 12))
>x : Symbol(x, Decl(contextuallyTypedIifeStrict.ts, 30, 10))
((x, y, z) => 42)();
>x : Symbol(x, Decl(contextuallyTypedIifeStrict.ts, 31, 2))
>y : Symbol(y, Decl(contextuallyTypedIifeStrict.ts, 31, 4))
>z : Symbol(z, Decl(contextuallyTypedIifeStrict.ts, 31, 7))

View file

@ -0,0 +1,271 @@
=== tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts ===
// arrow
(jake => { })("build");
>(jake => { })("build") : void
>(jake => { }) : (jake: string) => void
>jake => { } : (jake: string) => void
>jake : string
>"build" : "build"
// function expression
(function (cats) { })("lol");
>(function (cats) { })("lol") : void
>(function (cats) { }) : (cats: string) => void
>function (cats) { } : (cats: string) => void
>cats : string
>"lol" : "lol"
// Lots of Irritating Superfluous Parentheses
(function (x) { } ("!"));
>(function (x) { } ("!")) : void
>function (x) { } ("!") : void
>function (x) { } : (x: string) => void
>x : string
>"!" : "!"
((((function (y) { }))))("-");
>((((function (y) { }))))("-") : void
>((((function (y) { })))) : (y: string) => void
>(((function (y) { }))) : (y: string) => void
>((function (y) { })) : (y: string) => void
>(function (y) { }) : (y: string) => void
>function (y) { } : (y: string) => void
>y : string
>"-" : "-"
// multiple arguments
((a, b, c) => { })("foo", 101, false);
>((a, b, c) => { })("foo", 101, false) : void
>((a, b, c) => { }) : (a: string, b: number, c: boolean) => void
>(a, b, c) => { } : (a: string, b: number, c: boolean) => void
>a : string
>b : number
>c : boolean
>"foo" : "foo"
>101 : 101
>false : false
// default parameters
((m = 10) => m + 1)(12);
>((m = 10) => m + 1)(12) : number
>((m = 10) => m + 1) : (m?: number) => number
>(m = 10) => m + 1 : (m?: number) => number
>m : number
>10 : 10
>m + 1 : number
>m : number
>1 : 1
>12 : 12
((n = 10) => n + 1)();
>((n = 10) => n + 1)() : number
>((n = 10) => n + 1) : (n?: number) => number
>(n = 10) => n + 1 : (n?: number) => number
>n : number
>10 : 10
>n + 1 : number
>n : number
>1 : 1
// optional parameters
((j?) => j + 1)(12);
>((j?) => j + 1)(12) : number
>((j?) => j + 1) : (j?: number | undefined) => number
>(j?) => j + 1 : (j?: number | undefined) => number
>j : number | undefined
>j + 1 : number
>j : number | undefined
>1 : 1
>12 : 12
((k?) => k + 1)();
>((k?) => k + 1)() : number
>((k?) => k + 1) : (k?: undefined) => number
>(k?) => k + 1 : (k?: undefined) => number
>k : undefined
>k + 1 : number
>k : undefined
>1 : 1
((l, o?) => l + o)(12); // o should be any
>((l, o?) => l + o)(12) : number
>((l, o?) => l + o) : (l: number, o?: undefined) => number
>(l, o?) => l + o : (l: number, o?: undefined) => number
>l : number
>o : undefined
>l + o : number
>l : number
>o : undefined
>12 : 12
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
>((...numbers) => numbers.every(n => n > 0))(5,6,7) : boolean
>((...numbers) => numbers.every(n => n > 0)) : (...numbers: number[]) => boolean
>(...numbers) => numbers.every(n => n > 0) : (...numbers: number[]) => boolean
>numbers : number[]
>numbers.every(n => n > 0) : boolean
>numbers.every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>numbers : number[]
>every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: number) => boolean
>n : number
>n > 0 : boolean
>n : number
>0 : 0
>5 : 5
>6 : 6
>7 : 7
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
>((...mixed) => mixed.every(n => !!n))(5,'oops','oh no') : boolean
>((...mixed) => mixed.every(n => !!n)) : (...mixed: (string | number)[]) => boolean
>(...mixed) => mixed.every(n => !!n) : (...mixed: (string | number)[]) => boolean
>mixed : (string | number)[]
>mixed.every(n => !!n) : boolean
>mixed.every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>mixed : (string | number)[]
>every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>n => !!n : (n: string | number) => boolean
>n : string | number
>!!n : boolean
>!n : boolean
>n : string | number
>5 : 5
>'oops' : "oops"
>'oh no' : "oh no"
((...noNumbers) => noNumbers.some(n => n > 0))();
>((...noNumbers) => noNumbers.some(n => n > 0))() : boolean
>((...noNumbers) => noNumbers.some(n => n > 0)) : (...noNumbers: any[]) => boolean
>(...noNumbers) => noNumbers.some(n => n > 0) : (...noNumbers: any[]) => boolean
>noNumbers : any[]
>noNumbers.some(n => n > 0) : boolean
>noNumbers.some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>noNumbers : any[]
>some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: any) => boolean
>n : any
>n > 0 : boolean
>n : any
>0 : 0
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
>((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10) : boolean[]
>((first, ...rest) => first ? [] : rest.map(n => n > 0)) : (first: number, ...rest: number[]) => boolean[]
>(first, ...rest) => first ? [] : rest.map(n => n > 0) : (first: number, ...rest: number[]) => boolean[]
>first : number
>rest : number[]
>first ? [] : rest.map(n => n > 0) : boolean[]
>first : number
>[] : never[]
>rest.map(n => n > 0) : boolean[]
>rest.map : { <U>(this: [number, number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U]; <U>(this: [number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): U[]; }
>rest : number[]
>map : { <U>(this: [number, number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U]; <U>(this: [number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): U[]; }
>n => n > 0 : (n: number) => boolean
>n : number
>n > 0 : boolean
>n : number
>0 : 0
>8 : 8
>9 : 9
>10 : 10
// destructuring parameters (with defaults too!)
(({ q }) => q)({ q : 13 });
>(({ q }) => q)({ q : 13 }) : number
>(({ q }) => q) : ({q}: { q: number; }) => number
>({ q }) => q : ({q}: { q: number; }) => number
>q : number
>q : number
>{ q : 13 } : { q: number; }
>q : number
>13 : 13
(({ p = 14 }) => p)({ p : 15 });
>(({ p = 14 }) => p)({ p : 15 }) : number
>(({ p = 14 }) => p) : ({p}: { p: number; }) => number
>({ p = 14 }) => p : ({p}: { p: number; }) => number
>p : number
>14 : 14
>p : number
>{ p : 15 } : { p: number; }
>p : number
>15 : 15
(({ r = 17 } = { r: 18 }) => r)({r : 19});
>(({ r = 17 } = { r: 18 }) => r)({r : 19}) : number
>(({ r = 17 } = { r: 18 }) => r) : ({r}?: { r: number; }) => number
>({ r = 17 } = { r: 18 }) => r : ({r}?: { r: number; }) => number
>r : number
>17 : 17
>{ r: 18 } : { r: number; }
>r : number
>18 : 18
>r : number
>{r : 19} : { r: number; }
>r : number
>19 : 19
(({ u = 22 } = { u: 23 }) => u)();
>(({ u = 22 } = { u: 23 }) => u)() : number
>(({ u = 22 } = { u: 23 }) => u) : ({u}?: { u?: number; }) => number
>({ u = 22 } = { u: 23 }) => u : ({u}?: { u?: number; }) => number
>u : number
>22 : 22
>{ u: 23 } : { u?: number; }
>u : number
>23 : 23
>u : number
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
>twelve : any
>(f => f(12))(i => i) : any
>(f => f(12)) : (f: (i: any) => any) => any
>f => f(12) : (f: (i: any) => any) => any
>f : (i: any) => any
>f(12) : any
>f : (i: any) => any
>12 : 12
>i => i : (i: any) => any
>i : any
>i : any
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
>eleven : any
>(o => o.a(11))({ a: function(n) { return n; } }) : any
>(o => o.a(11)) : (o: { a: (n: any) => any; }) => any
>o => o.a(11) : (o: { a: (n: any) => any; }) => any
>o : { a: (n: any) => any; }
>o.a(11) : any
>o.a : (n: any) => any
>o : { a: (n: any) => any; }
>a : (n: any) => any
>11 : 11
>{ a: function(n) { return n; } } : { a: (n: any) => any; }
>a : (n: any) => any
>function(n) { return n; } : (n: any) => any
>n : any
>n : any
// missing arguments
(function(x, undefined) { return x; })(42);
>(function(x, undefined) { return x; })(42) : number
>(function(x, undefined) { return x; }) : (x: number, undefined: undefined) => number
>function(x, undefined) { return x; } : (x: number, undefined: undefined) => number
>x : number
>undefined : undefined
>x : number
>42 : 42
((x, y, z) => 42)();
>((x, y, z) => 42)() : number
>((x, y, z) => 42) : (x: undefined, y: undefined, z: undefined) => number
>(x, y, z) => 42 : (x: undefined, y: undefined, z: undefined) => number
>x : undefined
>y : undefined
>z : undefined
>42 : 42

File diff suppressed because one or more lines are too long

View file

@ -27,3 +27,6 @@
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
// missing arguments
(function(x, undefined) { return x; })(42);
((x, y, z) => 42)();

View file

@ -0,0 +1,33 @@
// @strictNullChecks: true
// arrow
(jake => { })("build");
// function expression
(function (cats) { })("lol");
// Lots of Irritating Superfluous Parentheses
(function (x) { } ("!"));
((((function (y) { }))))("-");
// multiple arguments
((a, b, c) => { })("foo", 101, false);
// default parameters
((m = 10) => m + 1)(12);
((n = 10) => n + 1)();
// optional parameters
((j?) => j + 1)(12);
((k?) => k + 1)();
((l, o?) => l + o)(12); // o should be any
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
((...noNumbers) => noNumbers.some(n => n > 0))();
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
// destructuring parameters (with defaults too!)
(({ q }) => q)({ q : 13 });
(({ p = 14 }) => p)({ p : 15 });
(({ r = 17 } = { r: 18 }) => r)({r : 19});
(({ u = 22 } = { u: 23 }) => u)();
// contextually typed parameters.
let twelve = (f => f(12))(i => i);
let eleven = (o => o.a(11))({ a: function(n) { return n; } });
// missing arguments
(function(x, undefined) { return x; })(42);
((x, y, z) => 42)();