Skip to content

Commit 321bb9a

Browse files
committed
Merge branch 'master' into type-guard-narrowing
2 parents 472afc4 + 683ecc9 commit 321bb9a

107 files changed

Lines changed: 4161 additions & 1664 deletions

File tree

Some content is hidden

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

AUTHORS.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ TypeScript is authored by:
88
* Basarat Ali Syed
99
* Ben Duffield
1010
* Bill Ticehurst
11+
* Brett Mayen
1112
* Bryan Forbes
1213
* Caitlin Potter
1314
* Chris Bubernak
@@ -17,11 +18,14 @@ TypeScript is authored by:
1718
* Dan Quirk
1819
* Daniel Rosenwasser
1920
* David Li
20-
* Dick van den Brink
21-
* Dirk Bäumer
21+
* Denis Nedelyaev
22+
* Dick van den Brink
23+
* Dirk Bäumer
24+
* Eyas Sharaiha
2225
* Frank Wallis
2326
* Gabriel Isenberg
2427
* Gilad Peleg
28+
* Graeme Wicksted
2529
* Guillaume Salles
2630
* Harald Niesche
2731
* Ingvar Stepanyan
@@ -31,30 +35,39 @@ TypeScript is authored by:
3135
* Jason Ramsay
3236
* Jed Mao
3337
* Johannes Rieken
38+
* John Vilk
3439
* Jonathan Bond-Caron
3540
* Jonathan Park
3641
* Jonathan Turner
3742
* Josh Kalderimis
43+
* Julian Williams
3844
* Kagami Sascha Rosylight
3945
* Keith Mashinter
46+
* Ken Howard
4047
* Kenji Imamula
4148
* Lorant Pinter
49+
* Martin Všetička
4250
* Masahiro Wakame
4351
* Max Deepfield
4452
* Micah Zoltu
4553
* Mohamed Hegazy
54+
* Nathan Shively-Sanders
4655
* Oleg Mihailik
4756
* Oleksandr Chekhovskyi
4857
* Paul van Brenk
4958
* Pedro Maltez
5059
* Philip Bulley
5160
* piloopin
61+
* @progre
62+
* Punya Biswal
5263
* Ron Buckton
5364
* Ryan Cavanaugh
65+
* Ryohei Ikegami
66+
* Sébastien Arod
5467
* Sheetal Nandi
5568
* Shengping Zhong
5669
* Shyyko Serhiy
57-
* Simon Hürlimann
70+
* Simon Hürlimann
5871
* Solal Pirelli
5972
* Stan Thomas
6073
* Steve Lucco
@@ -63,8 +76,10 @@ TypeScript is authored by:
6376
* togru
6477
* Tomas Grubliauskas
6578
* TruongSinh Tran-Nguyen
79+
* Viliv Vane
6680
* Vladimir Matveev
6781
* Wesley Wigham
82+
* York Yao
6883
* Yui Tanglertsampan
6984
* Zev Spitz
70-
* Zhengbo Li
85+
* Zhengbo Li

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.org/Microsoft/TypeScript.svg?branch=master)](https://travis-ci.org/Microsoft/TypeScript)
2-
[![npm version](https://badge.fury.io/js/typescript.svg)](http://badge.fury.io/js/typescript)
3-
[![Downloads](http://img.shields.io/npm/dm/TypeScript.svg)](https://npmjs.org/package/typescript)
2+
[![npm version](https://badge.fury.io/js/typescript.svg)](https://www.npmjs.com/package/typescript)
3+
[![Downloads](https://img.shields.io/npm/dm/TypeScript.svg)](https://www.npmjs.com/package/typescript)
44

55
# TypeScript
66

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"browserify": "latest",
3636
"istanbul": "latest",
3737
"mocha-fivemat-progress-reporter": "latest",
38-
"tslint": "latest",
38+
"tslint": "next",
39+
"typescript": "next",
3940
"tsd": "latest"
4041
},
4142
"scripts": {

scripts/tslint/booleanTriviaRule.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2-
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
3-
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
43

54
export class Rule extends Lint.Rules.AbstractRule {
65
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
@@ -19,7 +18,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
1918

2019
visitCallExpression(node: ts.CallExpression) {
2120
super.visitCallExpression(node);
22-
if (node.arguments) {
21+
if (node.arguments) {
2322
const targetCallSignature = this.checker.getResolvedSignature(node);
2423
if (!!targetCallSignature) {
2524
const targetParameters = targetCallSignature.getParameters();
@@ -37,14 +36,14 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
3736
let triviaContent: string;
3837
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
3938
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
40-
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); //+/-2 to remove /**/
39+
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
4140
}
4241
if (triviaContent !== param.getName()) {
4342
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
4443
}
4544
}
4645
}
4746
}
48-
}
47+
}
4948
}
5049
}

scripts/tslint/nextLineRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2-
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
33

44
const OPTION_CATCH = "check-catch";
55
const OPTION_ELSE = "check-else";

scripts/tslint/noNullRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2-
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
33

44

55
export class Rule extends Lint.Rules.AbstractRule {

scripts/tslint/preferConstRule.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2-
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
33

44

55
export class Rule extends Lint.Rules.AbstractRule {
@@ -101,13 +101,13 @@ class PreferConstWalker extends Lint.RuleWalker {
101101
this.visitBindingLiteralExpression(node as (ts.ArrayLiteralExpression | ts.ObjectLiteralExpression));
102102
}
103103
}
104-
104+
105105
private visitBindingLiteralExpression(node: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression) {
106106
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
107107
const pattern = node as ts.ObjectLiteralExpression;
108108
for (const element of pattern.properties) {
109109
if (element.name.kind === ts.SyntaxKind.Identifier) {
110-
this.markAssignment(element.name as ts.Identifier)
110+
this.markAssignment(element.name as ts.Identifier);
111111
}
112112
else if (isBindingPattern(element.name)) {
113113
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);

scripts/tslint/typeOperatorSpacingRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2-
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
33

44

55
export class Rule extends Lint.Rules.AbstractRule {

src/compiler/binder.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ namespace ts {
139139
file.classifiableNames = classifiableNames;
140140
}
141141

142+
file = undefined;
143+
options = undefined;
142144
parent = undefined;
143145
container = undefined;
144146
blockScopeContainer = undefined;
@@ -175,9 +177,14 @@ namespace ts {
175177
symbol.members = {};
176178
}
177179

178-
if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) {
179-
symbol.valueDeclaration = node;
180-
}
180+
if (symbolFlags & SymbolFlags.Value) {
181+
const valueDeclaration = symbol.valueDeclaration;
182+
if (!valueDeclaration ||
183+
(valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) {
184+
// other kinds of value declarations take precedence over modules
185+
symbol.valueDeclaration = node;
186+
}
187+
}
181188
}
182189

183190
// Should not be called on a declaration with a computed property name,

src/compiler/checker.ts

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ namespace ts {
122122

123123
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
124124

125-
const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false);
126-
const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false);
125+
const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
126+
const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
127127

128128
const globals: SymbolTable = {};
129129

@@ -200,6 +200,10 @@ namespace ts {
200200
"symbol": {
201201
type: esSymbolType,
202202
flags: TypeFlags.ESSymbol
203+
},
204+
"undefined": {
205+
type: undefinedType,
206+
flags: TypeFlags.ContainsUndefinedOrNull
203207
}
204208
};
205209

@@ -295,7 +299,12 @@ namespace ts {
295299
target.constEnumOnlyModule = false;
296300
}
297301
target.flags |= source.flags;
298-
if (!target.valueDeclaration && source.valueDeclaration) target.valueDeclaration = source.valueDeclaration;
302+
if (source.valueDeclaration &&
303+
(!target.valueDeclaration ||
304+
(target.valueDeclaration.kind === SyntaxKind.ModuleDeclaration && source.valueDeclaration.kind !== SyntaxKind.ModuleDeclaration))) {
305+
// other kinds of value declarations take precedence over modules
306+
target.valueDeclaration = source.valueDeclaration;
307+
}
299308
forEach(source.declarations, node => {
300309
target.declarations.push(node);
301310
});
@@ -2267,7 +2276,7 @@ namespace ts {
22672276
return false;
22682277
}
22692278
resolutionTargets.push(target);
2270-
resolutionResults.push(true);
2279+
resolutionResults.push(/*items*/ true);
22712280
resolutionPropertyNames.push(propertyName);
22722281
return true;
22732282
}
@@ -3339,7 +3348,7 @@ namespace ts {
33393348

33403349
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
33413350
if (!hasClassBaseType(classType)) {
3342-
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)];
3351+
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)];
33433352
}
33443353
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
33453354
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
@@ -3820,7 +3829,13 @@ namespace ts {
38203829
let minArgumentCount = -1;
38213830
for (let i = 0, n = declaration.parameters.length; i < n; i++) {
38223831
const param = declaration.parameters[i];
3823-
parameters.push(param.symbol);
3832+
let paramSymbol = param.symbol;
3833+
// Include parameter symbol instead of property symbol in the signature
3834+
if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
3835+
const resolvedSymbol = resolveName(param, paramSymbol.name, SymbolFlags.Value, undefined, undefined);
3836+
paramSymbol = resolvedSymbol;
3837+
}
3838+
parameters.push(paramSymbol);
38243839
if (param.type && param.type.kind === SyntaxKind.StringLiteral) {
38253840
hasStringLiterals = true;
38263841
}
@@ -3964,7 +3979,7 @@ namespace ts {
39643979
}
39653980

39663981
function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
3967-
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true);
3982+
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
39683983
}
39693984

39703985
function getErasedSignature(signature: Signature): Signature {
@@ -3974,7 +3989,7 @@ namespace ts {
39743989
signature.erasedSignatureCache = instantiateSignature(getErasedSignature(signature.target), signature.mapper);
39753990
}
39763991
else {
3977-
signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true);
3992+
signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
39783993
}
39793994
}
39803995
return signature.erasedSignatureCache;
@@ -5090,7 +5105,7 @@ namespace ts {
50905105
let result = Ternary.True;
50915106
const sourceTypes = source.types;
50925107
for (const sourceType of sourceTypes) {
5093-
const related = typeRelatedToSomeType(sourceType, target, false);
5108+
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
50945109
if (!related) {
50955110
return Ternary.False;
50965111
}
@@ -5488,7 +5503,7 @@ namespace ts {
54885503
const saveErrorInfo = errorInfo;
54895504
let related = isRelatedTo(s, t, reportErrors);
54905505
if (!related) {
5491-
related = isRelatedTo(t, s, false);
5506+
related = isRelatedTo(t, s, /*reportErrors*/ false);
54925507
if (!related) {
54935508
if (reportErrors) {
54945509
reportError(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
@@ -5615,7 +5630,7 @@ namespace ts {
56155630
let related: Ternary;
56165631
if (sourceStringType && sourceNumberType) {
56175632
// If we know for sure we're testing both string and numeric index types then only report errors from the second one
5618-
related = isRelatedTo(sourceStringType, targetType, false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
5633+
related = isRelatedTo(sourceStringType, targetType, /*reportErrors*/ false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
56195634
}
56205635
else {
56215636
related = isRelatedTo(sourceStringType || sourceNumberType, targetType, reportErrors);
@@ -6469,6 +6484,10 @@ namespace ts {
64696484
assumeTrue = !assumeTrue;
64706485
}
64716486
const typeInfo = primitiveTypeInfo[right.text];
6487+
// Don't narrow `undefined`
6488+
if (typeInfo && typeInfo.type === undefinedType) {
6489+
return type;
6490+
}
64726491
// If the type to be narrowed is any and we're checking a primitive with assumeTrue=true, return the primitive
64736492
if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
64746493
return typeInfo.type;
@@ -9859,7 +9878,7 @@ namespace ts {
98599878
return type;
98609879
}
98619880

9862-
function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
9881+
function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
98639882
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
98649883

98659884
const isAsync = isAsyncFunctionLike(node);
@@ -11346,11 +11365,17 @@ namespace ts {
1134611365
const errorNode: Node = (<FunctionLikeDeclaration>subsequentNode).name || subsequentNode;
1134711366
// TODO(jfreeman): These are methods, so handle computed name case
1134811367
if (node.name && (<FunctionLikeDeclaration>subsequentNode).name && (<Identifier>node.name).text === (<Identifier>(<FunctionLikeDeclaration>subsequentNode).name).text) {
11349-
// the only situation when this is possible (same kind\same name but different symbol) - mixed static and instance class members
11350-
Debug.assert(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature);
11351-
Debug.assert((node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static));
11352-
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
11353-
error(errorNode, diagnostic);
11368+
const reportError =
11369+
(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) &&
11370+
(node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static);
11371+
// we can get here in two cases
11372+
// 1. mixed static and instance class members
11373+
// 2. something with the same name was defined before the set of overloads that prevents them from merging
11374+
// here we'll report error only for the first case since for second we should already report error in binder
11375+
if (reportError) {
11376+
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
11377+
error(errorNode, diagnostic);
11378+
}
1135411379
return;
1135511380
}
1135611381
else if (nodeIsPresent((<FunctionLikeDeclaration>subsequentNode).body)) {
@@ -12885,13 +12910,13 @@ namespace ts {
1288512910
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
1288612911
const caseType = checkExpression(caseClause.expression);
1288712912

12888-
// Permit 'number[] | "foo"' to be asserted to 'string'.
12889-
if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) {
12890-
return;
12891-
}
12913+
const expressionTypeIsAssignableToCaseType =
12914+
// Permit 'number[] | "foo"' to be asserted to 'string'.
12915+
(expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) ||
12916+
isTypeAssignableTo(expressionType, caseType);
1289212917

12893-
if (!isTypeAssignableTo(expressionType, caseType)) {
12894-
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
12918+
if (!expressionTypeIsAssignableToCaseType) {
12919+
// 'expressionType is not assignable to caseType', try the reversed check and report errors if it fails
1289512920
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
1289612921
}
1289712922
}

0 commit comments

Comments
 (0)