@@ -6114,6 +6114,23 @@ namespace ts {
61146114 }
61156115 }
61166116
6117+ function resolveDeferredMappedTypeMembers(type: DeferredMappedType) {
6118+ const indexInfo = type.targetIndexInfo;
6119+ const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true;
6120+ const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional;
6121+ const stringIndexInfo = indexInfo && createIndexInfo(inferDeferredMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly);
6122+ const members = createSymbolTable();
6123+ for (const prop of type.sourceProperties) {
6124+ const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0);
6125+ const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol;
6126+ inferredProp.declarations = prop.declarations;
6127+ inferredProp.propertyType = getTypeOfSymbol(prop);
6128+ inferredProp.mappedType = type.mappedType;
6129+ members.set(prop.escapedName, inferredProp);
6130+ }
6131+ setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
6132+ }
6133+
61176134 /** Resolve the members of a mapped type { [P in K]: T } */
61186135 function resolveMappedTypeMembers(type: MappedType) {
61196136 const members: SymbolTable = createSymbolTable();
@@ -6253,6 +6270,9 @@ namespace ts {
62536270 else if ((<ObjectType>type).objectFlags & ObjectFlags.ClassOrInterface) {
62546271 resolveClassOrInterfaceMembers(<InterfaceType>type);
62556272 }
6273+ else if ((<DeferredMappedType>type).objectFlags & ObjectFlags.Deferred) {
6274+ resolveDeferredMappedTypeMembers(type as DeferredMappedType);
6275+ }
62566276 else if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
62576277 resolveAnonymousTypeMembers(<AnonymousType>type);
62586278 }
@@ -11291,35 +11311,23 @@ namespace ts {
1129111311 }
1129211312
1129311313 function createDeferredMappedType(source: Type, target: MappedType) {
11294- const properties = getPropertiesOfType(source);
11295- let indexInfo = getIndexInfoOfType(source, IndexKind.String);
11296- if (properties.length === 0 && !indexInfo) {
11314+ const properties = getPropertiesOfType(source);
11315+ let indexInfo = getIndexInfoOfType(source, IndexKind.String);
11316+ if (properties.length === 0 && !indexInfo) {
11317+ return undefined;
11318+ }
11319+ // If any property contains context sensitive functions that have been skipped, the source type
11320+ // is incomplete and we can't infer a meaningful input type.
11321+ for (const prop of properties) {
11322+ if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) {
1129711323 return undefined;
1129811324 }
11299- const readonlyMask = target.declaration.readonlyToken ? false : true;
11300- const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
11301- const members = createSymbolTable();
11302- for (const prop of properties) {
11303- const propType = getTypeOfSymbol(prop);
11304- // If any property contains context sensitive functions that have been skipped, the source type
11305- // is incomplete and we can't infer a meaningful input type.
11306- if (propType.flags & TypeFlags.ContainsAnyFunctionType) {
11307- return undefined;
11308- }
11309- const checkFlags = CheckFlags.Deferred | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0);
11310- const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as DeferredTransientSymbol;
11311- inferredProp.declarations = prop.declarations;
11312- inferredProp.propertyType = propType;
11313- inferredProp.mappedType = target;
11314- members.set(prop.escapedName, inferredProp);
11315- }
11316- if (indexInfo) {
11317- // TODO: Defer this too.
11318- // (probably the simplest way is to have a special type that defers the creation of (at least) its index info in
11319- // resolveStructuredTypeMembers
11320- indexInfo = createIndexInfo(inferDeferredMappedType(indexInfo.type, target), readonlyMask && indexInfo.isReadonly);
11321- }
11322- return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined);
11325+ }
11326+ const deferred = createObjectType(ObjectFlags.Deferred | ObjectFlags.Anonymous, undefined) as DeferredMappedType;
11327+ deferred.mappedType = target;
11328+ deferred.sourceProperties = properties;
11329+ deferred.targetIndexInfo = indexInfo;
11330+ return deferred;
1132311331 }
1132411332
1132511333 function inferDeferredMappedType(sourceType: Type, target: MappedType): Type {
0 commit comments