Skip to content

Commit 34b35df

Browse files
committed
Merge branch 'master' into fixInstanceOfFunction
2 parents cedfd7e + 1b880f8 commit 34b35df

File tree

66 files changed

+1523
-102
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1523
-102
lines changed

.github/ISSUE_TEMPLATE/Bug_report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Please fill in the *entire* template below.
1616
-->
1717

1818
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
19-
**TypeScript Version:** 3.1.0-dev.201xxxxx
19+
**TypeScript Version:** 3.2.0-dev.201xxxxx
2020

2121
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
2222
**Search Terms:**

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript",
33
"author": "Microsoft Corp.",
44
"homepage": "http://typescriptlang.org/",
5-
"version": "3.1.0",
5+
"version": "3.2.0",
66
"license": "Apache-2.0",
77
"description": "TypeScript is a language for application scale JavaScript development",
88
"keywords": [

src/compiler/checker.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ namespace ts {
7777
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
7878
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
7979
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
80+
const strictBindCallApply = getStrictOptionValue(compilerOptions, "strictBindCallApply");
8081
const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
8182
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
8283
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
@@ -476,6 +477,8 @@ namespace ts {
476477

477478
let globalObjectType: ObjectType;
478479
let globalFunctionType: ObjectType;
480+
let globalCallableFunctionType: ObjectType;
481+
let globalNewableFunctionType: ObjectType;
479482
let globalArrayType: GenericType;
480483
let globalReadonlyArrayType: GenericType;
481484
let globalStringType: ObjectType;
@@ -1708,7 +1711,9 @@ namespace ts {
17081711
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
17091712
Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum));
17101713
// Block-scoped variables cannot be used before their definition
1711-
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) ? d : undefined);
1714+
const declaration = find(
1715+
result.declarations,
1716+
d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) || isInJSFile(d) && !!getJSDocEnumTag(d));
17121717

17131718
if (declaration === undefined) return Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined");
17141719

@@ -7391,8 +7396,12 @@ namespace ts {
73917396
if (symbol && symbolIsValue(symbol)) {
73927397
return symbol;
73937398
}
7394-
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
7395-
const symbol = getPropertyOfObjectType(globalFunctionType, name);
7399+
const functionType = resolved === anyFunctionType ? globalFunctionType :
7400+
resolved.callSignatures.length ? globalCallableFunctionType :
7401+
resolved.constructSignatures.length ? globalNewableFunctionType :
7402+
undefined;
7403+
if (functionType) {
7404+
const symbol = getPropertyOfObjectType(functionType, name);
73967405
if (symbol) {
73977406
return symbol;
73987407
}
@@ -13250,10 +13259,8 @@ namespace ts {
1325013259
const targetCount = getParameterCount(target);
1325113260
const sourceRestType = getEffectiveRestType(source);
1325213261
const targetRestType = getEffectiveRestType(target);
13253-
const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) :
13254-
sourceRestType ? targetCount :
13255-
Math.min(sourceCount, targetCount);
13256-
13262+
const targetNonRestCount = targetRestType ? targetCount - 1 : targetCount;
13263+
const paramCount = sourceRestType ? targetNonRestCount : Math.min(sourceCount, targetNonRestCount);
1325713264
const sourceThisType = getThisTypeOfSignature(source);
1325813265
if (sourceThisType) {
1325913266
const targetThisType = getThisTypeOfSignature(target);
@@ -13900,15 +13907,17 @@ namespace ts {
1390013907
if (!inferredType) {
1390113908
const signature = context.signature;
1390213909
if (signature) {
13903-
if (inference.contraCandidates && (!inference.candidates || inference.candidates.length === 1 && inference.candidates[0].flags & TypeFlags.Never)) {
13904-
// If we have contravariant inferences, but no covariant inferences or a single
13905-
// covariant inference of 'never', we find the best common subtype and treat that
13906-
// as a single covariant candidate.
13907-
inference.candidates = [getContravariantInference(inference)];
13908-
inference.contraCandidates = undefined;
13909-
}
13910-
if (inference.candidates) {
13911-
inferredType = getCovariantInference(inference, signature);
13910+
const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
13911+
if (inference.contraCandidates) {
13912+
const inferredContravariantType = getContravariantInference(inference);
13913+
// If we have both co- and contra-variant inferences, we prefer the contra-variant inference
13914+
// unless the co-variant inference is a subtype and not 'never'.
13915+
inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) &&
13916+
isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ?
13917+
inferredCovariantType : inferredContravariantType;
13918+
}
13919+
else if (inferredCovariantType) {
13920+
inferredType = inferredCovariantType;
1391213921
}
1391313922
else if (context.flags & InferenceFlags.NoDefault) {
1391413923
// We use silentNeverType as the wildcard that signals no inferences.
@@ -19684,7 +19693,10 @@ namespace ts {
1968419693
checkCandidate = candidate;
1968519694
}
1968619695
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
19687-
candidateForArgumentError = checkCandidate;
19696+
// Give preference to error candidates that have no rest parameters (as they are more specific)
19697+
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
19698+
candidateForArgumentError = checkCandidate;
19699+
}
1968819700
continue;
1968919701
}
1969019702
if (excludeArgument) {
@@ -19697,7 +19709,10 @@ namespace ts {
1969719709
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
1969819710
}
1969919711
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
19700-
candidateForArgumentError = checkCandidate;
19712+
// Give preference to error candidates that have no rest parameters (as they are more specific)
19713+
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
19714+
candidateForArgumentError = checkCandidate;
19715+
}
1970119716
continue;
1970219717
}
1970319718
}
@@ -28029,8 +28044,11 @@ namespace ts {
2802928044
function getAugmentedPropertiesOfType(type: Type): Symbol[] {
2803028045
type = getApparentType(type);
2803128046
const propsByName = createSymbolTable(getPropertiesOfType(type));
28032-
if (typeHasCallOrConstructSignatures(type)) {
28033-
forEach(getPropertiesOfType(globalFunctionType), p => {
28047+
const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType :
28048+
getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType :
28049+
undefined;
28050+
if (functionType) {
28051+
forEach(getPropertiesOfType(functionType), p => {
2803428052
if (!propsByName.has(p.escapedName)) {
2803528053
propsByName.set(p.escapedName, p);
2803628054
}
@@ -28810,6 +28828,8 @@ namespace ts {
2881028828
globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true);
2881128829
globalObjectType = getGlobalType("Object" as __String, /*arity*/ 0, /*reportErrors*/ true);
2881228830
globalFunctionType = getGlobalType("Function" as __String, /*arity*/ 0, /*reportErrors*/ true);
28831+
globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
28832+
globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
2881328833
globalStringType = getGlobalType("String" as __String, /*arity*/ 0, /*reportErrors*/ true);
2881428834
globalNumberType = getGlobalType("Number" as __String, /*arity*/ 0, /*reportErrors*/ true);
2881528835
globalBooleanType = getGlobalType("Boolean" as __String, /*arity*/ 0, /*reportErrors*/ true);

src/compiler/commandLineParser.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,14 @@ namespace ts {
373373
category: Diagnostics.Strict_Type_Checking_Options,
374374
description: Diagnostics.Enable_strict_checking_of_function_types
375375
},
376+
{
377+
name: "strictBindCallApply",
378+
type: "boolean",
379+
strictFlag: true,
380+
showInSimplifiedHelpView: true,
381+
category: Diagnostics.Strict_Type_Checking_Options,
382+
description: Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
383+
},
376384
{
377385
name: "strictPropertyInitialization",
378386
type: "boolean",

src/compiler/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace ts {
22
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
33
// If changing the text in this section, be sure to test `configureNightly` too.
4-
export const versionMajorMinor = "3.1";
4+
export const versionMajorMinor = "3.2";
55
/** The version of the TypeScript compiler release */
66
export const version = `${versionMajorMinor}.0-dev`;
77
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3759,6 +3759,10 @@
37593759
"category": "Message",
37603760
"code": 6213
37613761
},
3762+
"Enable strict 'bind', 'call', and 'apply' methods on functions.": {
3763+
"category": "Message",
3764+
"code": 6214
3765+
},
37623766

37633767
"Projects to reference": {
37643768
"category": "Message",

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4427,6 +4427,7 @@ namespace ts {
44274427
sourceRoot?: string;
44284428
strict?: boolean;
44294429
strictFunctionTypes?: boolean; // Always combine with strict property
4430+
strictBindCallApply?: boolean; // Always combine with strict property
44304431
strictNullChecks?: boolean; // Always combine with strict property
44314432
strictPropertyInitialization?: boolean; // Always combine with strict property
44324433
stripInternal?: boolean;

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7085,7 +7085,7 @@ namespace ts {
70857085
return !!(compilerOptions.declaration || compilerOptions.composite);
70867086
}
70877087

7088-
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
7088+
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictBindCallApply" | "strictPropertyInitialization" | "alwaysStrict";
70897089

70907090
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
70917091
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];

src/harness/virtualFileSystemWithWatch.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace ts.TestFSWithWatch {
44
content: `/// <reference no-default-lib="true"/>
55
interface Boolean {}
66
interface Function {}
7+
interface CallableFunction {}
8+
interface NewableFunction {}
79
interface IArguments {}
810
interface Number { toExponential: any; }
911
interface Object {}

src/lib/es5.d.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,66 @@ interface FunctionConstructor {
295295

296296
declare const Function: FunctionConstructor;
297297

298+
interface CallableFunction extends Function {
299+
/**
300+
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
301+
* @param thisArg The object to be used as the this object.
302+
* @param args An array of argument values to be passed to the function.
303+
*/
304+
apply<T, R>(this: (this: T) => R, thisArg: T): R;
305+
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
306+
307+
/**
308+
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
309+
* @param thisArg The object to be used as the this object.
310+
* @param args Argument values to be passed to the function.
311+
*/
312+
call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;
313+
314+
/**
315+
* For a given function, creates a bound function that has the same body as the original function.
316+
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
317+
* @param thisArg The object to be used as the this object.
318+
* @param args Arguments to bind to the parameters of the function.
319+
*/
320+
bind<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T): (...args: A) => R;
321+
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
322+
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
323+
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
324+
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
325+
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
326+
}
327+
328+
interface NewableFunction extends Function {
329+
/**
330+
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
331+
* @param thisArg The object to be used as the this object.
332+
* @param args An array of argument values to be passed to the function.
333+
*/
334+
apply<T>(this: new () => T, thisArg: T): void;
335+
apply<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, args: A): void;
336+
337+
/**
338+
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
339+
* @param thisArg The object to be used as the this object.
340+
* @param args Argument values to be passed to the function.
341+
*/
342+
call<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, ...args: A): void;
343+
344+
/**
345+
* For a given function, creates a bound function that has the same body as the original function.
346+
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
347+
* @param thisArg The object to be used as the this object.
348+
* @param args Arguments to bind to the parameters of the function.
349+
*/
350+
bind<A extends any[], R>(this: new (...args: A) => R, thisArg: any): new (...args: A) => R;
351+
bind<A0, A extends any[], R>(this: new (arg0: A0, ...args: A) => R, thisArg: any, arg0: A0): new (...args: A) => R;
352+
bind<A0, A1, A extends any[], R>(this: new (arg0: A0, arg1: A1, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1): new (...args: A) => R;
353+
bind<A0, A1, A2, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2): new (...args: A) => R;
354+
bind<A0, A1, A2, A3, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2, arg3: A3): new (...args: A) => R;
355+
bind<AX, R>(this: new (...args: AX[]) => R, thisArg: any, ...args: AX[]): new (...args: AX[]) => R;
356+
}
357+
298358
interface IArguments {
299359
[index: number]: any;
300360
length: number;

0 commit comments

Comments
 (0)