Skip to content

Commit 21daffd

Browse files
committed
Merge branch 'master' into better-js-constructor-checks
2 parents 5b083a0 + 4f37555 commit 21daffd

File tree

56 files changed

+1106
-200
lines changed

Some content is hidden

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

56 files changed

+1106
-200
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13290,13 +13290,13 @@ namespace ts {
1329013290
&& every(symbol.declarations, d => !isFunctionLike(d) || !!(d.flags & NodeFlags.Deprecated));
1329113291
}
1329213292

13293-
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
13293+
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags, reportDeprecated?: boolean) {
1329413294
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
1329513295
const propName = accessNode && isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode);
1329613296
if (propName !== undefined) {
1329713297
const prop = getPropertyOfType(objectType, propName);
1329813298
if (prop) {
13299-
if (accessNode && prop.valueDeclaration?.flags & NodeFlags.Deprecated && isUncalledFunctionReference(accessNode, prop)) {
13299+
if (reportDeprecated && accessNode && prop.valueDeclaration?.flags & NodeFlags.Deprecated && isUncalledFunctionReference(accessNode, prop)) {
1330013300
const deprecatedNode = accessExpression?.argumentExpression ?? (isIndexedAccessTypeNode(accessNode) ? accessNode.indexType : accessNode);
1330113301
errorOrSuggestion(/* isError */ false, deprecatedNode, Diagnostics._0_is_deprecated, propName as string);
1330213302
}
@@ -13666,7 +13666,7 @@ namespace ts {
1366613666
}
1366713667
return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments) : getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
1366813668
}
13669-
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol);
13669+
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol, /* reportDeprecated */ true);
1367013670
}
1367113671

1367213672
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
@@ -17279,7 +17279,11 @@ namespace ts {
1727917279
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false);
1728017280
if (result) {
1728117281
result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
17282-
if (result) {
17282+
// Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the
17283+
// element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems
17284+
// with index type assignability as the types for the excluded discriminants are still included
17285+
// in the index type.
17286+
if (result && !(isTupleType(source) && isTupleType(type))) {
1728317287
result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
1728417288
}
1728517289
}
@@ -17504,6 +17508,7 @@ namespace ts {
1750417508
for (let i = 0; i < maxArity; i++) {
1750517509
const targetFlags = i < targetArity ? target.target.elementFlags[i] : targetRestFlag;
1750617510
const sourceFlags = isTupleType(source) && i < sourceArity ? source.target.elementFlags[i] : sourceRestFlag;
17511+
let canExcludeDiscriminants = !!excludedProperties;
1750717512
if (sourceFlags && targetFlags) {
1750817513
if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic) ||
1750917514
(sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable))) {
@@ -17520,6 +17525,15 @@ namespace ts {
1752017525
return Ternary.False;
1752117526
}
1752217527
}
17528+
// We can only exclude discriminant properties if we have not yet encountered a variable-length element.
17529+
if (canExcludeDiscriminants) {
17530+
if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) {
17531+
canExcludeDiscriminants = false;
17532+
}
17533+
if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) {
17534+
continue;
17535+
}
17536+
}
1752317537
const sourceType = getTypeArguments(source)[Math.min(i, sourceArity - 1)];
1752417538
const targetType = getTypeArguments(target)[Math.min(i, targetArity - 1)];
1752517539
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType;
@@ -21800,6 +21814,12 @@ namespace ts {
2180021814
emptyObjectType;
2180121815
}
2180221816

21817+
// We can't narrow a union based off instanceof without negated types see #31576 for more info
21818+
if (!assumeTrue && rightType.flags & TypeFlags.Union) {
21819+
const nonConstructorTypeInUnion = find((<UnionType>rightType).types, (t) => !isConstructorType(t));
21820+
if (!nonConstructorTypeInUnion) return type;
21821+
}
21822+
2180321823
return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
2180421824
}
2180521825

@@ -36092,16 +36112,19 @@ namespace ts {
3609236112
function isTypeDeclarationName(name: Node): boolean {
3609336113
return name.kind === SyntaxKind.Identifier &&
3609436114
isTypeDeclaration(name.parent) &&
36095-
name.parent.name === name;
36115+
getNameOfDeclaration(name.parent) === name;
3609636116
}
3609736117

36098-
function isTypeDeclaration(node: Node): node is TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration | ImportClause | ImportSpecifier | ExportSpecifier {
36118+
function isTypeDeclaration(node: Node): node is TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | EnumDeclaration | ImportClause | ImportSpecifier | ExportSpecifier {
3609936119
switch (node.kind) {
3610036120
case SyntaxKind.TypeParameter:
3610136121
case SyntaxKind.ClassDeclaration:
3610236122
case SyntaxKind.InterfaceDeclaration:
3610336123
case SyntaxKind.TypeAliasDeclaration:
3610436124
case SyntaxKind.EnumDeclaration:
36125+
case SyntaxKind.JSDocTypedefTag:
36126+
case SyntaxKind.JSDocCallbackTag:
36127+
case SyntaxKind.JSDocEnumTag:
3610536128
return true;
3610636129
case SyntaxKind.ImportClause:
3610736130
return (node as ImportClause).isTypeOnly;

src/compiler/parser.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,19 +2701,10 @@ namespace ts {
27012701
return finishNode(factory.createThisTypeNode(), pos);
27022702
}
27032703

2704-
function parseJSDocAllType(postFixEquals: boolean): JSDocAllType | JSDocOptionalType {
2704+
function parseJSDocAllType(): JSDocAllType | JSDocOptionalType {
27052705
const pos = getNodePos();
27062706
nextToken();
2707-
2708-
const node = factory.createJSDocAllType();
2709-
if (postFixEquals) {
2710-
// Trim the trailing `=` from the `*=` token
2711-
const end = Math.max(getNodePos() - 1, pos);
2712-
return finishNode(factory.createJSDocOptionalType(finishNode(node, pos, end)), pos);
2713-
}
2714-
else {
2715-
return finishNode(node, pos);
2716-
}
2707+
return finishNode(factory.createJSDocAllType(), pos);
27172708
}
27182709

27192710
function parseJSDocNonNullableType(): TypeNode {
@@ -3396,12 +3387,14 @@ namespace ts {
33963387
case SyntaxKind.ObjectKeyword:
33973388
// If these are followed by a dot, then parse these out as a dotted type reference instead.
33983389
return tryParse(parseKeywordAndNoDot) || parseTypeReference();
3399-
case SyntaxKind.AsteriskToken:
3400-
return parseJSDocAllType(/*postfixEquals*/ false);
34013390
case SyntaxKind.AsteriskEqualsToken:
3402-
return parseJSDocAllType(/*postfixEquals*/ true);
3391+
// If there is '*=', treat it as * followed by postfix =
3392+
scanner.reScanAsteriskEqualsToken();
3393+
// falls through
3394+
case SyntaxKind.AsteriskToken:
3395+
return parseJSDocAllType();
34033396
case SyntaxKind.QuestionQuestionToken:
3404-
// If there is '??', consider that is prefix '?' in JSDoc type.
3397+
// If there is '??', treat it as prefix-'?' in JSDoc type.
34053398
scanner.reScanQuestionToken();
34063399
// falls through
34073400
case SyntaxKind.QuestionToken:

src/compiler/scanner.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace ts {
3434
getTokenFlags(): TokenFlags;
3535
reScanGreaterToken(): SyntaxKind;
3636
reScanSlashToken(): SyntaxKind;
37+
reScanAsteriskEqualsToken(): SyntaxKind;
3738
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
3839
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
3940
scanJsxIdentifier(): SyntaxKind;
@@ -954,6 +955,7 @@ namespace ts {
954955
getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags,
955956
getTokenFlags: () => tokenFlags,
956957
reScanGreaterToken,
958+
reScanAsteriskEqualsToken,
957959
reScanSlashToken,
958960
reScanTemplateToken,
959961
reScanTemplateHeadOrNoSubstitutionTemplate,
@@ -2086,6 +2088,12 @@ namespace ts {
20862088
return token;
20872089
}
20882090

2091+
function reScanAsteriskEqualsToken(): SyntaxKind {
2092+
Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='");
2093+
pos = tokenPos + 1;
2094+
return token = SyntaxKind.EqualsToken;
2095+
}
2096+
20892097
function reScanSlashToken(): SyntaxKind {
20902098
if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) {
20912099
let p = tokenPos + 1;

src/compiler/transformers/ts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,7 @@ namespace ts {
15311531
case SyntaxKind.LiteralType:
15321532
switch ((<LiteralTypeNode>node).literal.kind) {
15331533
case SyntaxKind.StringLiteral:
1534+
case SyntaxKind.NoSubstitutionTemplateLiteral:
15341535
return factory.createIdentifier("String");
15351536

15361537
case SyntaxKind.PrefixUnaryExpression:

src/compiler/utilities.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,7 @@ namespace ts {
22202220
}
22212221
return AssignmentDeclarationKind.ObjectDefinePropertyValue;
22222222
}
2223-
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || !isAccessExpression(expr.left)) {
2223+
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || !isAccessExpression(expr.left) || isVoidZero(getRightMostAssignedExpression(expr))) {
22242224
return AssignmentDeclarationKind.None;
22252225
}
22262226
if (isBindableStaticNameExpression(expr.left.expression, /*excludeThisKeyword*/ true) && getElementOrPropertyAccessName(expr.left) === "prototype" && isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
@@ -2230,6 +2230,10 @@ namespace ts {
22302230
return getAssignmentDeclarationPropertyAccessKind(expr.left);
22312231
}
22322232

2233+
function isVoidZero(node: Node) {
2234+
return isVoidExpression(node) && isNumericLiteral(node.expression) && node.expression.text === "0";
2235+
}
2236+
22332237
/**
22342238
* Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
22352239
* throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)

src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4068,11 +4068,11 @@
40684068
</Str>
40694069
<Disp Icon="Str" />
40704070
</Item>
4071-
<Item ItemId=";Did_you_mean_to_use_a_Colon_When_following_property_names_in_an_object_literal_implies_a_destructuri_1312" ItemType="0" PsrId="306" Leaf="true">
4071+
<Item ItemId=";Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_1312" ItemType="0" PsrId="306" Leaf="true">
40724072
<Str Cat="Text">
4073-
<Val><![CDATA[Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.]]></Val>
4073+
<Val><![CDATA[Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern.]]></Val>
40744074
<Tgt Cat="Text" Stat="Loc" Orig="New">
4075-
<Val><![CDATA[你的意思是使用 ":" 吗? 在对象文字中采用属性名称时,"=" 表示解构赋值。]]></Val>
4075+
<Val><![CDATA[你的意思是使用 ":" 吗? 当包含对象文字属于解构模式时,"=" 只能跟在属性名称的后面。]]></Val>
40764076
</Tgt>
40774077
</Str>
40784078
<Disp Icon="Str" />

src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,7 +2593,7 @@
25932593
<Str Cat="Text">
25942594
<Val><![CDATA[Cannot find lib definition for '{0}'.]]></Val>
25952595
<Tgt Cat="Text" Stat="Loc" Orig="New">
2596-
<Val><![CDATA[Définition de lib introuvable pour '{0}'.]]></Val>
2596+
<Val><![CDATA[Définition de bibliothèque introuvable pour '{0}'.]]></Val>
25972597
</Tgt>
25982598
</Str>
25992599
<Disp Icon="Str" />
@@ -2602,7 +2602,7 @@
26022602
<Str Cat="Text">
26032603
<Val><![CDATA[Cannot find lib definition for '{0}'. Did you mean '{1}'?]]></Val>
26042604
<Tgt Cat="Text" Stat="Loc" Orig="New">
2605-
<Val><![CDATA[Définition de lib introuvable pour '{0}'. Est-ce qu'il ne s'agit pas plutôt de '{1}' ?]]></Val>
2605+
<Val><![CDATA[Définition de bibliothèque introuvable pour '{0}'. Est-ce qu'il ne s'agit pas plutôt de '{1}' ?]]></Val>
26062606
</Tgt>
26072607
</Str>
26082608
<Disp Icon="Str" />

src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2574,7 +2574,7 @@
25742574
<Str Cat="Text">
25752575
<Val><![CDATA[Cannot find lib definition for '{0}'.]]></Val>
25762576
<Tgt Cat="Text" Stat="Loc" Orig="New">
2577-
<Val><![CDATA[Não é possível encontrar a definição de lib para '{0}'.]]></Val>
2577+
<Val><![CDATA[Não é possível encontrar a definição de biblioteca para '{0}'.]]></Val>
25782578
</Tgt>
25792579
</Str>
25802580
<Disp Icon="Str" />
@@ -2583,7 +2583,7 @@
25832583
<Str Cat="Text">
25842584
<Val><![CDATA[Cannot find lib definition for '{0}'. Did you mean '{1}'?]]></Val>
25852585
<Tgt Cat="Text" Stat="Loc" Orig="New">
2586-
<Val><![CDATA[Não é possível encontrar a definição de lib para '{0}'. Você quis dizer '{1}'?]]></Val>
2586+
<Val><![CDATA[Não é possível encontrar a definição de biblioteca para '{0}'. Você quis dizer '{1}'?]]></Val>
25872587
</Tgt>
25882588
</Str>
25892589
<Disp Icon="Str" />

src/server/project.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ namespace ts.server {
282282
this.languageServiceEnabled = true;
283283
if (projectService.syntaxOnly) {
284284
this.compilerOptions.noResolve = true;
285+
this.compilerOptions.types = [];
285286
}
286287

287288
this.setInternalCompilerOptionsForEmittingJsFiles();

0 commit comments

Comments
 (0)