@@ -14262,7 +14262,36 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
14262
14262
* maps primitive types and type parameters are to their apparent types.
14263
14263
*/
14264
14264
function getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[] {
14265
- return getSignaturesOfStructuredType(getReducedApparentType(type), kind);
14265
+ const result = getSignaturesOfStructuredType(getReducedApparentType(type), kind);
14266
+ if (kind === SignatureKind.Call && !length(result) && type.flags & TypeFlags.Union) {
14267
+ if ((type as UnionType).arrayFallbackSignatures) {
14268
+ return (type as UnionType).arrayFallbackSignatures!;
14269
+ }
14270
+ // If the union is all different instantiations of a member of the global array type...
14271
+ let memberName: __String;
14272
+ if (everyType(type, t => !!t.symbol?.parent && isArrayOrTupleSymbol(t.symbol.parent) && (!memberName ? (memberName = t.symbol.escapedName, true) : memberName === t.symbol.escapedName))) {
14273
+ // Transform the type from `(A[] | B[])["member"]` to `(A | B)[]["member"]` (since we pretend array is covariant anyway)
14274
+ const arrayArg = mapType(type, t => getMappedType((isReadonlyArraySymbol(t.symbol.parent) ? globalReadonlyArrayType : globalArrayType).typeParameters![0], (t as AnonymousType).mapper!));
14275
+ const arrayType = createArrayType(arrayArg, someType(type, t => isReadonlyArraySymbol(t.symbol.parent)));
14276
+ return (type as UnionType).arrayFallbackSignatures = getSignaturesOfType(getTypeOfPropertyOfType(arrayType, memberName!)!, kind);
14277
+ }
14278
+ (type as UnionType).arrayFallbackSignatures = result;
14279
+ }
14280
+ return result;
14281
+ }
14282
+
14283
+ function isArrayOrTupleSymbol(symbol: Symbol | undefined) {
14284
+ if (!symbol || !globalArrayType.symbol || !globalReadonlyArrayType.symbol) {
14285
+ return false;
14286
+ }
14287
+ return !!getSymbolIfSameReference(symbol, globalArrayType.symbol) || !!getSymbolIfSameReference(symbol, globalReadonlyArrayType.symbol);
14288
+ }
14289
+
14290
+ function isReadonlyArraySymbol(symbol: Symbol | undefined) {
14291
+ if (!symbol || !globalReadonlyArrayType.symbol) {
14292
+ return false;
14293
+ }
14294
+ return !!getSymbolIfSameReference(symbol, globalReadonlyArrayType.symbol);
14266
14295
}
14267
14296
14268
14297
function findIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) {
@@ -16486,36 +16515,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16486
16515
}
16487
16516
16488
16517
function getUnionOrIntersectionTypePredicate(signatures: readonly Signature[], kind: TypeFlags | undefined): TypePredicate | undefined {
16489
- let first : TypePredicate | undefined;
16518
+ let last : TypePredicate | undefined;
16490
16519
const types: Type[] = [];
16491
16520
for (const sig of signatures) {
16492
16521
const pred = getTypePredicateOfSignature(sig);
16493
- if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) {
16494
- if (kind !== TypeFlags.Intersection) {
16495
- continue;
16496
- }
16497
- else {
16498
- return; // intersections demand all members be type predicates for the result to have a predicate
16499
- }
16500
- }
16501
-
16502
- if (first) {
16503
- if (!typePredicateKindsMatch(first, pred)) {
16504
- // No common type predicate.
16522
+ if (pred) {
16523
+ // Constituent type predicates must all have matching kinds. We don't create composite type predicates for assertions.
16524
+ if (pred.kind !== TypePredicateKind.This && pred.kind !== TypePredicateKind.Identifier || last && !typePredicateKindsMatch(last, pred)) {
16505
16525
return undefined;
16506
16526
}
16527
+ last = pred;
16528
+ types.push(pred.type);
16507
16529
}
16508
16530
else {
16509
- first = pred;
16531
+ // In composite union signatures we permit and ignore signatures with a return type `false`.
16532
+ const returnType = kind !== TypeFlags.Intersection ? getReturnTypeOfSignature(sig) : undefined;
16533
+ if (returnType !== falseType && returnType !== regularFalseType) {
16534
+ return undefined;
16535
+ }
16510
16536
}
16511
- types.push(pred.type);
16512
16537
}
16513
- if (!first) {
16514
- // No signatures had a type predicate.
16538
+ if (!last) {
16515
16539
return undefined;
16516
16540
}
16517
16541
const compositeType = getUnionOrIntersectionType(types, kind);
16518
- return createTypePredicate(first .kind, first .parameterName, first .parameterIndex, compositeType);
16542
+ return createTypePredicate(last .kind, last .parameterName, last .parameterIndex, compositeType);
16519
16543
}
16520
16544
16521
16545
function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {
@@ -29294,6 +29318,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
29294
29318
case SyntaxKind.NumericLiteral:
29295
29319
case SyntaxKind.BigIntLiteral:
29296
29320
case SyntaxKind.NoSubstitutionTemplateLiteral:
29321
+ case SyntaxKind.TemplateExpression:
29297
29322
case SyntaxKind.TrueKeyword:
29298
29323
case SyntaxKind.FalseKeyword:
29299
29324
case SyntaxKind.NullKeyword:
@@ -32590,8 +32615,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
32590
32615
// can be specified by users through attributes property.
32591
32616
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
32592
32617
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
32618
+ const checkAttributesType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(attributesType) : attributesType;
32593
32619
return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(
32594
- attributesType ,
32620
+ checkAttributesType ,
32595
32621
paramType,
32596
32622
relation,
32597
32623
reportErrors ? node.tagName : undefined,
@@ -34514,6 +34540,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34514
34540
}
34515
34541
return getRegularTypeOfLiteralType(exprType);
34516
34542
}
34543
+ const links = getNodeLinks(node);
34544
+ links.assertionExpressionType = exprType;
34517
34545
checkSourceElement(type);
34518
34546
checkNodeDeferred(node);
34519
34547
return getTypeFromTypeNode(type);
@@ -34538,9 +34566,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34538
34566
}
34539
34567
34540
34568
function checkAssertionDeferred(node: JSDocTypeAssertion | AssertionExpression) {
34541
- const { type, expression } = getAssertionTypeAndExpression(node);
34569
+ const { type } = getAssertionTypeAndExpression(node);
34542
34570
const errNode = isParenthesizedExpression(node) ? type : node;
34543
- const exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression)));
34571
+ const links = getNodeLinks(node);
34572
+ Debug.assertIsDefined(links.assertionExpressionType);
34573
+ const exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(links.assertionExpressionType));
34544
34574
const targetType = getTypeFromTypeNode(type);
34545
34575
if (!isErrorType(targetType)) {
34546
34576
addLazyDiagnostic(() => {
@@ -37342,7 +37372,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
37342
37372
texts.push(span.literal.text);
37343
37373
types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType);
37344
37374
}
37345
- return isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node, /*contextFlags*/ undefined) || unknownType, isTemplateLiteralContextualType) ? getTemplateLiteralType(texts, types) : stringType;
37375
+ if (isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node, /*contextFlags*/ undefined) || unknownType, isTemplateLiteralContextualType)) {
37376
+ return getTemplateLiteralType(texts, types);
37377
+ }
37378
+ const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluateTemplateExpression(node);
37379
+ return evaluated ? getFreshTypeOfLiteralType(getStringLiteralType(evaluated)) : stringType;
37346
37380
}
37347
37381
37348
37382
function isTemplateLiteralContextualType(type: Type): boolean {
@@ -43619,7 +43653,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
43619
43653
return value;
43620
43654
}
43621
43655
43622
- function evaluate(expr: Expression, location: Declaration): string | number | undefined {
43656
+ function evaluate(expr: Expression, location? : Declaration): string | number | undefined {
43623
43657
switch (expr.kind) {
43624
43658
case SyntaxKind.PrefixUnaryExpression:
43625
43659
const value = evaluate((expr as PrefixUnaryExpression).operand, location);
@@ -43676,11 +43710,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
43676
43710
const symbol = resolveEntityName(expr, SymbolFlags.Value, /*ignoreErrors*/ true);
43677
43711
if (symbol) {
43678
43712
if (symbol.flags & SymbolFlags.EnumMember) {
43679
- return evaluateEnumMember(expr, symbol, location);
43713
+ return location ? evaluateEnumMember(expr, symbol, location) : getEnumMemberValue(symbol.valueDeclaration as EnumMember );
43680
43714
}
43681
43715
if (isConstVariable(symbol)) {
43682
43716
const declaration = symbol.valueDeclaration as VariableDeclaration | undefined;
43683
- if (declaration && !declaration.type && declaration.initializer && declaration !== location && isBlockScopedNameDeclaredBeforeUse(declaration, location)) {
43717
+ if (declaration && !declaration.type && declaration.initializer && (!location || declaration !== location && isBlockScopedNameDeclaredBeforeUse(declaration, location) )) {
43684
43718
return evaluate(declaration.initializer, declaration);
43685
43719
}
43686
43720
}
@@ -43695,7 +43729,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
43695
43729
const name = escapeLeadingUnderscores(((expr as ElementAccessExpression).argumentExpression as StringLiteralLike).text);
43696
43730
const member = rootSymbol.exports!.get(name);
43697
43731
if (member) {
43698
- return evaluateEnumMember(expr, member, location);
43732
+ return location ? evaluateEnumMember(expr, member, location) : getEnumMemberValue(member.valueDeclaration as EnumMember );
43699
43733
}
43700
43734
}
43701
43735
}
@@ -43717,7 +43751,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
43717
43751
return getEnumMemberValue(declaration as EnumMember);
43718
43752
}
43719
43753
43720
- function evaluateTemplateExpression(expr: TemplateExpression, location: Declaration) {
43754
+ function evaluateTemplateExpression(expr: TemplateExpression, location? : Declaration) {
43721
43755
let result = expr.head.text;
43722
43756
for (const span of expr.templateSpans) {
43723
43757
const value = evaluate(span.expression, location);
@@ -46985,7 +47019,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
46985
47019
if (requestedExternalEmitHelperNames.has(name)) continue;
46986
47020
requestedExternalEmitHelperNames.add(name);
46987
47021
46988
- const symbol = getSymbol(helpersModule.exports! , escapeLeadingUnderscores(name), SymbolFlags.Value);
47022
+ const symbol = getSymbol(getExportsOfModule( helpersModule) , escapeLeadingUnderscores(name), SymbolFlags.Value);
46989
47023
if (!symbol) {
46990
47024
error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name);
46991
47025
}
0 commit comments