@@ -30789,57 +30789,67 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30789
30789
}
30790
30790
30791
30791
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
+ }
30798
30809
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
+ ),
30813
30817
),
30818
+ isTypeAssignableTo,
30814
30819
),
30815
- isTypeAssignableTo,
30816
30820
);
30817
30821
}
30818
30822
30819
30823
function discriminateContextualTypeByJSXAttributes(node: JsxAttributes, contextualType: UnionType) {
30824
+ const key = `D${getNodeId(node)},${getTypeId(contextualType)}`;
30825
+ const cached = getCachedType(key);
30826
+ if (cached) return cached;
30820
30827
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
+ ),
30840
30850
),
30851
+ isTypeAssignableTo,
30841
30852
),
30842
- isTypeAssignableTo,
30843
30853
);
30844
30854
}
30845
30855
0 commit comments