Skip to content

Commit 004dc89

Browse files
authored
Use elipses for reverse mapped types in nested positions (#28494)
1 parent d99de73 commit 004dc89

File tree

3 files changed

+79
-31
lines changed

3 files changed

+79
-31
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,11 +3458,7 @@ namespace ts {
34583458
return symbolToTypeNode(typeAlias, context, SymbolFlags.Type);
34593459
}
34603460
else {
3461-
context.approximateLength += 3;
3462-
if (!(context.flags & NodeBuilderFlags.NoTruncation)) {
3463-
return createTypeReferenceNode(createIdentifier("..."), /*typeArguments*/ undefined);
3464-
}
3465-
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
3461+
return createElidedInformationPlaceholder(context);
34663462
}
34673463
}
34683464
else {
@@ -3477,11 +3473,7 @@ namespace ts {
34773473

34783474
const depth = context.symbolDepth.get(id) || 0;
34793475
if (depth > 10) {
3480-
context.approximateLength += 3;
3481-
if (!(context.flags & NodeBuilderFlags.NoTruncation)) {
3482-
return createTypeReferenceNode(createIdentifier("..."), /*typeArguments*/ undefined);
3483-
}
3484-
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
3476+
return createElidedInformationPlaceholder(context);
34853477
}
34863478
context.symbolDepth.set(id, depth + 1);
34873479
context.visitedTypes.set(typeId, true);
@@ -3674,10 +3666,15 @@ namespace ts {
36743666
typeElements.push(<ConstructSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context));
36753667
}
36763668
if (resolvedType.stringIndexInfo) {
3677-
const indexInfo = resolvedType.objectFlags & ObjectFlags.ReverseMapped ?
3678-
createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) :
3679-
resolvedType.stringIndexInfo;
3680-
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context));
3669+
let indexSignature: IndexSignatureDeclaration;
3670+
if (resolvedType.objectFlags & ObjectFlags.ReverseMapped) {
3671+
indexSignature = indexInfoToIndexSignatureDeclarationHelper(createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), IndexKind.String, context);
3672+
indexSignature.type = createElidedInformationPlaceholder(context);
3673+
}
3674+
else {
3675+
indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context);
3676+
}
3677+
typeElements.push(indexSignature);
36813678
}
36823679
if (resolvedType.numberIndexInfo) {
36833680
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context));
@@ -3711,8 +3708,17 @@ namespace ts {
37113708
}
37123709
}
37133710

3711+
function createElidedInformationPlaceholder(context: NodeBuilderContext) {
3712+
context.approximateLength += 3;
3713+
if (!(context.flags & NodeBuilderFlags.NoTruncation)) {
3714+
return createTypeReferenceNode(createIdentifier("..."), /*typeArguments*/ undefined);
3715+
}
3716+
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
3717+
}
3718+
37143719
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
3715-
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
3720+
const propertyIsReverseMapped = !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped);
3721+
const propertyType = propertyIsReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
37163722
anyType : getTypeOfSymbol(propertySymbol);
37173723
const saveEnclosingDeclaration = context.enclosingDeclaration;
37183724
context.enclosingDeclaration = undefined;
@@ -3741,8 +3747,14 @@ namespace ts {
37413747
}
37423748
else {
37433749
const savedFlags = context.flags;
3744-
context.flags |= !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) ? NodeBuilderFlags.InReverseMappedType : 0;
3745-
const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
3750+
context.flags |= propertyIsReverseMapped ? NodeBuilderFlags.InReverseMappedType : 0;
3751+
let propertyTypeNode: TypeNode;
3752+
if (propertyIsReverseMapped && !!(savedFlags & NodeBuilderFlags.InReverseMappedType)) {
3753+
propertyTypeNode = createElidedInformationPlaceholder(context);
3754+
}
3755+
else {
3756+
propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
3757+
}
37463758
context.flags = savedFlags;
37473759

37483760
const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined;

tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,53 @@
1818

1919
verify.quickInfoAt('1', `const out: {
2020
a: {
21-
a: any;
21+
a: ...;
2222
};
2323
}`);
2424
verify.quickInfoAt('2', `function foo<{
2525
a: {
26-
a: any;
26+
a: ...;
2727
};
2828
}>(deep: Deep<{
2929
a: {
30-
a: any;
30+
a: ...;
3131
};
3232
}>): {
3333
a: {
34-
a: any;
34+
a: ...;
3535
};
3636
}`);
3737
verify.quickInfoAt('3', `(property) a: {
3838
a: {
39-
a: any;
39+
a: ...;
4040
};
4141
}`);
4242
verify.quickInfoAt('4', `(property) a: {
4343
a: {
44-
a: any;
44+
a: ...;
4545
};
4646
}`);
4747
verify.quickInfoAt('5', `(property) a: {
4848
a: {
49-
a: any;
49+
a: ...;
5050
};
5151
}`);
5252
verify.quickInfoAt('6', `const oub: {
53-
[x: string]: any;
53+
[x: string]: ...;
5454
}`);
5555
verify.quickInfoAt('7', `function foo<{
56-
[x: string]: any;
56+
[x: string]: ...;
5757
}>(deep: Deep<{
58-
[x: string]: any;
58+
[x: string]: ...;
5959
}>): {
60-
[x: string]: any;
60+
[x: string]: ...;
6161
}`);
6262
verify.quickInfoAt('8', `{
63-
[x: string]: any;
63+
[x: string]: ...;
6464
}`);
6565
verify.quickInfoAt('9', `{
66-
[x: string]: any;
66+
[x: string]: ...;
6767
}`);
6868
verify.quickInfoAt('10', `{
69-
[x: string]: any;
69+
[x: string]: ...;
7070
}`);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////interface IAction {
4+
//// type: string;
5+
////}
6+
////
7+
////type Reducer<S> = (state: S, action: IAction) => S
8+
////
9+
////function combineReducers<S>(reducers: { [K in keyof S]: Reducer<S[K]> }): Reducer<S> {
10+
//// const dummy = {} as S;
11+
//// return () => dummy;
12+
////}
13+
////
14+
////const test_inner = (test: string, action: IAction) => {
15+
//// return 'dummy';
16+
////}
17+
////const test = combineReducers({
18+
//// test_inner
19+
////});
20+
////
21+
////const test_outer = combineReducers({
22+
//// test
23+
////});
24+
////
25+
////// '{test: { test_inner: any } }'
26+
////type FinalType/*1*/ = ReturnType<typeof test_outer>;
27+
////
28+
////var k: FinalType;
29+
////k.test.test_inner/*2*/
30+
31+
verify.quickInfoAt("1", `type FinalType = {
32+
test: {
33+
test_inner: ...;
34+
};
35+
}`);
36+
verify.quickInfoAt("2", `(property) test_inner: string`);

0 commit comments

Comments
 (0)