Only create literal types if a contexutal type is present and indicates that they may be necessary.

This commit is contained in:
Daniel Rosenwasser
2024-07-11 00:23:25 +00:00
parent 972e9a70c6
commit 0570a597aa

View File

@@ -24860,6 +24860,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return t.flags & TypeFlags.Intersection ? some((t as IntersectionType).types, isUnitType) : isUnitType(t);
}
function typeMayWitnessLiteralTypes(target: Type): boolean {
if (target.flags & TypeFlags.Union) {
return some((target as UnionType).types, typeMayWitnessLiteralTypes);
}
// We do not account for `any` because `getContextFreeTypeOfExpression`
// specifically pushes a cached `any`.
const nonBaseFlags = ~(TypeFlags.Unknown | TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt | TypeFlags.Never | TypeFlags.Nullable);
return (target.flags & nonBaseFlags) !== 0;
}
function extractUnitType(type: Type) {
return type.flags & TypeFlags.Intersection ? find((type as IntersectionType).types, isUnitType) || type : type;
}
@@ -40583,14 +40594,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case SyntaxKind.NullKeyword:
return nullWideningType;
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.StringLiteral:
case SyntaxKind.StringLiteral: {
const contextualType = getContextualType(node, ContextFlags.NoConstraints);
if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return stringType;
return hasSkipDirectInferenceFlag(node) ?
blockedStringType :
getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text));
case SyntaxKind.NumericLiteral:
}
case SyntaxKind.NumericLiteral: {
const contextualType = getContextualType(node, ContextFlags.NoConstraints);
if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return numberType;
checkGrammarNumericLiteral(node as NumericLiteral);
return getFreshTypeOfLiteralType(getNumberLiteralType(+(node as NumericLiteral).text));
}
case SyntaxKind.BigIntLiteral:
const contextualType = getContextualType(node, ContextFlags.NoConstraints);
if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return bigintType;
checkGrammarBigIntLiteral(node as BigIntLiteral);
return getFreshTypeOfLiteralType(getBigIntLiteralType({
negative: false,