@@ -30789,57 +30789,67 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3078930789 }
3079030790
3079130791 function discriminateContextualTypeByObjectMembers(node: ObjectLiteralExpression, contextualType: UnionType) {
30792- return getMatchingUnionConstituentForObjectLiteral(contextualType, node) || discriminateTypeByDiscriminableItems(
30793- contextualType,
30794- concatenate(
30795- map(
30796- filter(node.properties, (p): p is PropertyAssignment | ShorthandPropertyAssignment => {
30797- if (!p.symbol) {
30792+ const key = `D${getNodeId(node)},${getTypeId(contextualType)}`;
30793+ return getCachedType(key) ?? setCachedType(
30794+ key,
30795+ getMatchingUnionConstituentForObjectLiteral(contextualType, node) ?? discriminateTypeByDiscriminableItems(
30796+ contextualType,
30797+ concatenate(
30798+ map(
30799+ filter(node.properties, (p): p is PropertyAssignment | ShorthandPropertyAssignment => {
30800+ if (!p.symbol) {
30801+ return false;
30802+ }
30803+ if (p.kind === SyntaxKind.PropertyAssignment) {
30804+ return isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName);
30805+ }
30806+ if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
30807+ return isDiscriminantProperty(contextualType, p.symbol.escapedName);
30808+ }
3079830809 return false;
30799- }
30800- if (p.kind === SyntaxKind.PropertyAssignment) {
30801- return isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName);
30802- }
30803- if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
30804- return isDiscriminantProperty(contextualType, p.symbol.escapedName);
30805- }
30806- return false;
30807- }),
30808- prop => ([() => getContextFreeTypeOfExpression(prop.kind === SyntaxKind.PropertyAssignment ? prop.initializer : prop.name), prop.symbol.escapedName] as const),
30809- ),
30810- map(
30811- filter(getPropertiesOfType(contextualType), s => !!(s.flags & SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)),
30812- s => [() => undefinedType, s.escapedName] as const,
30810+ }),
30811+ prop => ([() => getContextFreeTypeOfExpression(prop.kind === SyntaxKind.PropertyAssignment ? prop.initializer : prop.name), prop.symbol.escapedName] as const),
30812+ ),
30813+ map(
30814+ filter(getPropertiesOfType(contextualType), s => !!(s.flags & SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)),
30815+ s => [() => undefinedType, s.escapedName] as const,
30816+ ),
3081330817 ),
30818+ isTypeAssignableTo,
3081430819 ),
30815- isTypeAssignableTo,
3081630820 );
3081730821 }
3081830822
3081930823 function discriminateContextualTypeByJSXAttributes(node: JsxAttributes, contextualType: UnionType) {
30824+ const key = `D${getNodeId(node)},${getTypeId(contextualType)}`;
30825+ const cached = getCachedType(key);
30826+ if (cached) return cached;
3082030827 const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
30821- return discriminateTypeByDiscriminableItems(
30822- contextualType,
30823- concatenate(
30824- map(
30825- filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))),
30826- prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => getContextFreeTypeOfExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as const),
30827- ),
30828- map(
30829- filter(getPropertiesOfType(contextualType), s => {
30830- if (!(s.flags & SymbolFlags.Optional) || !node?.symbol?.members) {
30831- return false;
30832- }
30833- const element = node.parent.parent;
30834- if (s.escapedName === jsxChildrenPropertyName && isJsxElement(element) && getSemanticJsxChildren(element.children).length) {
30835- return false;
30836- }
30837- return !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName);
30838- }),
30839- s => [() => undefinedType, s.escapedName] as const,
30828+ return setCachedType(
30829+ key,
30830+ discriminateTypeByDiscriminableItems(
30831+ contextualType,
30832+ concatenate(
30833+ map(
30834+ filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))),
30835+ prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => getContextFreeTypeOfExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as const),
30836+ ),
30837+ map(
30838+ filter(getPropertiesOfType(contextualType), s => {
30839+ if (!(s.flags & SymbolFlags.Optional) || !node?.symbol?.members) {
30840+ return false;
30841+ }
30842+ const element = node.parent.parent;
30843+ if (s.escapedName === jsxChildrenPropertyName && isJsxElement(element) && getSemanticJsxChildren(element.children).length) {
30844+ return false;
30845+ }
30846+ return !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName);
30847+ }),
30848+ s => [() => undefinedType, s.escapedName] as const,
30849+ ),
3084030850 ),
30851+ isTypeAssignableTo,
3084130852 ),
30842- isTypeAssignableTo,
3084330853 );
3084430854 }
3084530855
0 commit comments