Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serialization of accessor types in declaration files. #61392

Merged
merged 1 commit into from
Mar 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
@@ -6136,10 +6136,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
serializeExistingTypeNode(context, typeNode, addUndefined) {
return serializeExistingTypeNode(context as NodeBuilderContext, typeNode, !!addUndefined);
},
serializeReturnTypeForSignature(syntacticContext, signatureDeclaration) {
serializeReturnTypeForSignature(syntacticContext, signatureDeclaration, symbol) {
const context = syntacticContext as NodeBuilderContext;
const signature = getSignatureFromDeclaration(signatureDeclaration);
const returnType = context.enclosingSymbolTypes.get(getSymbolId(getSymbolOfDeclaration(signatureDeclaration))) ?? instantiateType(getReturnTypeOfSignature(signature), context.mapper);
symbol ??= getSymbolOfDeclaration(signatureDeclaration);
const returnType = context.enclosingSymbolTypes.get(getSymbolId(symbol)) ?? instantiateType(getReturnTypeOfSignature(signature), context.mapper);
return serializeInferredReturnTypeForSignature(context, signature, returnType);
},
serializeTypeOfExpression(syntacticContext, expr) {
@@ -6153,7 +6154,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
symbol ??= getSymbolOfDeclaration(declaration);
let type = context.enclosingSymbolTypes?.get(getSymbolId(symbol));
if (type === undefined) {
type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
type = symbol.flags & SymbolFlags.Accessor && declaration.kind === SyntaxKind.SetAccessor ? instantiateType(getWriteTypeOfSymbol(symbol), context.mapper) :
symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
? instantiateType(getWidenedLiteralType(getTypeOfSymbol(symbol)), context.mapper)
: errorType;
}
@@ -7386,12 +7388,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (propertySymbol.flags & SymbolFlags.Accessor) {
const writeType = getWriteTypeOfSymbol(propertySymbol);
if (propertyType !== writeType && !isErrorType(propertyType) && !isErrorType(writeType)) {
const symbolMapper = getSymbolLinks(propertySymbol).mapper;
const getterDeclaration = getDeclarationOfKind<GetAccessorDeclaration>(propertySymbol, SyntaxKind.GetAccessor)!;
const getterSignature = getSignatureFromDeclaration(getterDeclaration);
typeElements.push(
setCommentRange(
context,
signatureToSignatureDeclarationHelper(getterSignature, SyntaxKind.GetAccessor, context, { name: propertyName }) as GetAccessorDeclaration,
signatureToSignatureDeclarationHelper(symbolMapper ? instantiateSignature(getterSignature, symbolMapper) : getterSignature, SyntaxKind.GetAccessor, context, { name: propertyName }) as GetAccessorDeclaration,
getterDeclaration,
),
);
@@ -7400,7 +7403,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
typeElements.push(
setCommentRange(
context,
signatureToSignatureDeclarationHelper(setterSignature, SyntaxKind.SetAccessor, context, { name: propertyName }) as SetAccessorDeclaration,
signatureToSignatureDeclarationHelper(symbolMapper ? instantiateSignature(setterSignature, symbolMapper) : setterSignature, SyntaxKind.SetAccessor, context, { name: propertyName }) as SetAccessorDeclaration,
setterDeclaration,
),
);
@@ -8665,6 +8668,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const addUndefinedForParameter = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration, context.enclosingDeclaration);
const decl = declaration ?? symbol.valueDeclaration ?? getDeclarationWithTypeAnnotation(symbol) ?? symbol.declarations?.[0];
if (decl) {
const restore = addSymbolTypeToContext(context, symbol, type);
if (isAccessor(decl)) {
result = syntacticNodeBuilder.serializeTypeOfAccessor(decl, symbol, context);
}
@@ -8673,10 +8677,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
&& !nodeIsSynthesized(decl)
&& !(getObjectFlags(type) & ObjectFlags.RequiresWidening)
) {
const restore = addSymbolTypeToContext(context, symbol, type);
result = syntacticNodeBuilder.serializeTypeOfDeclaration(decl, symbol, context);
restore();
}
restore();
}
if (!result) {
if (addUndefinedForParameter) {
8 changes: 4 additions & 4 deletions src/compiler/expressionToTypeNode.ts
Original file line number Diff line number Diff line change
@@ -763,7 +763,7 @@ export function createSyntacticTypeNodeBuilder(
return withNewScope(context, node, () => serializeTypeAnnotationOfDeclaration(accessorType, context, node, symbol) ?? inferTypeOfDeclaration(node, symbol, context));
}
if (accessorDeclarations.getAccessor) {
return withNewScope(context, accessorDeclarations.getAccessor, () => createReturnFromSignature(accessorDeclarations.getAccessor!, /*symbol*/ undefined, context));
return withNewScope(context, accessorDeclarations.getAccessor, () => createReturnFromSignature(accessorDeclarations.getAccessor!, symbol, context));
}
return undefined;
}
@@ -854,14 +854,14 @@ export function createSyntacticTypeNodeBuilder(
return resolver.serializeTypeOfExpression(context, node) ?? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}

function inferReturnTypeOfSignatureSignature(node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext, reportFallback: boolean) {
function inferReturnTypeOfSignatureSignature(node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext, symbol: Symbol | undefined, reportFallback: boolean) {
if (reportFallback) {
context.tracker.reportInferenceFallback(node);
}
if (context.noInferenceFallback === true) {
return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
return resolver.serializeReturnTypeForSignature(context, node) ?? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
return resolver.serializeReturnTypeForSignature(context, node, symbol) ?? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}

function inferAccessorType(node: GetAccessorDeclaration | SetAccessorDeclaration, allAccessors: AllAccessorDeclarations, context: SyntacticTypeNodeBuilderContext, symbol: Symbol | undefined, reportFallback: boolean = true): TypeNode | undefined {
@@ -1276,7 +1276,7 @@ export function createSyntacticTypeNodeBuilder(
else if (isValueSignatureDeclaration(fn)) {
returnType = typeFromSingleReturnExpression(fn, context);
}
return returnType.type !== undefined ? returnType.type : inferReturnTypeOfSignatureSignature(fn, context, reportFallback && returnType.reportFallback && !returnTypeNode);
return returnType.type !== undefined ? returnType.type : inferReturnTypeOfSignatureSignature(fn, context, symbol, reportFallback && returnType.reportFallback && !returnTypeNode);
}

function typeFromSingleReturnExpression(declaration: FunctionLikeDeclaration | undefined, context: SyntacticTypeNodeBuilderContext): SyntacticResult {
2 changes: 1 addition & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
@@ -10553,7 +10553,7 @@ export interface SyntacticTypeNodeBuilderResolver {
isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean;
isEntityNameVisible(context: SyntacticTypeNodeBuilderContext, entityName: EntityNameOrEntityNameExpression, shouldComputeAliasToMakeVisible?: boolean): SymbolVisibilityResult;
serializeExistingTypeNode(context: SyntacticTypeNodeBuilderContext, node: TypeNode, addUndefined?: boolean): TypeNode | undefined;
serializeReturnTypeForSignature(context: SyntacticTypeNodeBuilderContext, signatureDeclaration: SignatureDeclaration | JSDocSignature): TypeNode | undefined;
serializeReturnTypeForSignature(context: SyntacticTypeNodeBuilderContext, signatureDeclaration: SignatureDeclaration | JSDocSignature, symbol: Symbol | undefined): TypeNode | undefined;
serializeTypeOfExpression(context: SyntacticTypeNodeBuilderContext, expr: Expression): TypeNode;
serializeTypeOfDeclaration(context: SyntacticTypeNodeBuilderContext, node: HasInferredType | GetAccessorDeclaration | SetAccessorDeclaration, symbol: Symbol | undefined): TypeNode | undefined;
serializeNameOfParameter(context: SyntacticTypeNodeBuilderContext, parameter: ParameterDeclaration): BindingName | string;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization.ts] ////

//// [declarationEmitGenericTypeParamerSerialization.ts]
function wrapper<T>(value: T) {
return {
m() { return value; },
get g() { return value; },
}
}

export const w = wrapper(0)


//// [declarationEmitGenericTypeParamerSerialization.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.w = void 0;
function wrapper(value) {
return {
m: function () { return value; },
get g() { return value; },
};
}
exports.w = wrapper(0);


//// [declarationEmitGenericTypeParamerSerialization.d.ts]
export declare const w: {
m(): number;
readonly g: number;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization.ts] ////

=== declarationEmitGenericTypeParamerSerialization.ts ===
function wrapper<T>(value: T) {
>wrapper : Symbol(wrapper, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 17))
>value : Symbol(value, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 20))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 17))

return {
m() { return value; },
>m : Symbol(m, Decl(declarationEmitGenericTypeParamerSerialization.ts, 1, 10))
>value : Symbol(value, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 20))

get g() { return value; },
>g : Symbol(g, Decl(declarationEmitGenericTypeParamerSerialization.ts, 2, 28))
>value : Symbol(value, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 20))
}
}

export const w = wrapper(0)
>w : Symbol(w, Decl(declarationEmitGenericTypeParamerSerialization.ts, 7, 12))
>wrapper : Symbol(wrapper, Decl(declarationEmitGenericTypeParamerSerialization.ts, 0, 0))

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization.ts] ////

=== declarationEmitGenericTypeParamerSerialization.ts ===
function wrapper<T>(value: T) {
>wrapper : <T>(value: T) => { m(): T; readonly g: T; }
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^

return {
>{ m() { return value; }, get g() { return value; }, } : { m(): T; readonly g: T; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^

m() { return value; },
>m : () => T
> : ^^^^^^^
>value : T
> : ^

get g() { return value; },
>g : T
> : ^
>value : T
> : ^
}
}

export const w = wrapper(0)
>w : { m(): number; readonly g: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>wrapper(0) : { m(): number; readonly g: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>wrapper : <T>(value: T) => { m(): T; readonly g: T; }
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>0 : 0
> : ^

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization2.ts] ////

//// [declarationEmitGenericTypeParamerSerialization2.ts]
type ExpandRecursively<T> = {} & {
[P in keyof T]: T[P]
}

type G<T = string> = {
get readonlyProperty(): T;
field: T;
method(p: T): T;
fnField: (p: T) => T;
set writeOnlyProperty(p: T);
get property(): T;
set property(p: T);
get divergentProperty(): string | T;
set divergentProperty(p: number | T);
};

export const x = (() => null! as ExpandRecursively<G>)();


function makeV() {
type X<T> = {
get readonlyProperty(): T;
field: T;
method(p: T): T;
fnField: (p: T) => T;
set writeOnlyProperty(p: T);
get property(): T;
set property(p: T);
get divergentProperty(): string | T;
set divergentProperty(p: number | T);
}
return null! as X<number>
}

export const v = makeV();


//// [declarationEmitGenericTypeParamerSerialization2.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.v = exports.x = void 0;
exports.x = (function () { return null; })();
function makeV() {
return null;
}
exports.v = makeV();


//// [declarationEmitGenericTypeParamerSerialization2.d.ts]
export declare const x: {
readonly readonlyProperty: string;
field: string;
method: (p: string) => string;
fnField: (p: string) => string;
writeOnlyProperty: string;
property: string;
divergentProperty: string;
};
export declare const v: {
readonly readonlyProperty: number;
field: number;
method(p: number): number;
fnField: (p: number) => number;
writeOnlyProperty: number;
property: number;
get divergentProperty(): string | number;
set divergentProperty(p: number);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization2.ts] ////

=== declarationEmitGenericTypeParamerSerialization2.ts ===
type ExpandRecursively<T> = {} & {
>ExpandRecursively : Symbol(ExpandRecursively, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 0, 23))

[P in keyof T]: T[P]
>P : Symbol(P, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 1, 3))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 0, 23))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 0, 23))
>P : Symbol(P, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 1, 3))
}

type G<T = string> = {
>G : Symbol(G, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 2, 1))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

get readonlyProperty(): T;
>readonlyProperty : Symbol(readonlyProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 22))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

field: T;
>field : Symbol(field, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 5, 28))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

method(p: T): T;
>method : Symbol(method, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 6, 11))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 7, 9))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

fnField: (p: T) => T;
>fnField : Symbol(fnField, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 7, 18))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 8, 12))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

set writeOnlyProperty(p: T);
>writeOnlyProperty : Symbol(writeOnlyProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 8, 23))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 9, 24))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

get property(): T;
>property : Symbol(property, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 9, 30), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 10, 20))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

set property(p: T);
>property : Symbol(property, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 9, 30), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 10, 20))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 11, 15))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

get divergentProperty(): string | T;
>divergentProperty : Symbol(divergentProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 11, 21), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 12, 38))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

set divergentProperty(p: number | T);
>divergentProperty : Symbol(divergentProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 11, 21), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 12, 38))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 13, 24))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 4, 7))

};

export const x = (() => null! as ExpandRecursively<G>)();
>x : Symbol(x, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 16, 12))
>ExpandRecursively : Symbol(ExpandRecursively, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 0, 0))
>G : Symbol(G, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 2, 1))


function makeV() {
>makeV : Symbol(makeV, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 16, 57))

type X<T> = {
>X : Symbol(X, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 19, 18))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

get readonlyProperty(): T;
>readonlyProperty : Symbol(readonlyProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 15))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

field: T;
>field : Symbol(field, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 21, 30))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

method(p: T): T;
>method : Symbol(method, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 22, 13))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 23, 11))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

fnField: (p: T) => T;
>fnField : Symbol(fnField, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 23, 20))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 24, 14))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

set writeOnlyProperty(p: T);
>writeOnlyProperty : Symbol(writeOnlyProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 24, 25))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 25, 26))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

get property(): T;
>property : Symbol(property, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 25, 32), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 26, 22))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

set property(p: T);
>property : Symbol(property, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 25, 32), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 26, 22))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 27, 17))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

get divergentProperty(): string | T;
>divergentProperty : Symbol(divergentProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 27, 23), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 28, 40))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))

set divergentProperty(p: number | T);
>divergentProperty : Symbol(divergentProperty, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 27, 23), Decl(declarationEmitGenericTypeParamerSerialization2.ts, 28, 40))
>p : Symbol(p, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 29, 26))
>T : Symbol(T, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 20, 9))
}
return null! as X<number>
>X : Symbol(X, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 19, 18))
}

export const v = makeV();
>v : Symbol(v, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 34, 12))
>makeV : Symbol(makeV, Decl(declarationEmitGenericTypeParamerSerialization2.ts, 16, 57))

Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//// [tests/cases/compiler/declarationEmitGenericTypeParamerSerialization2.ts] ////

=== declarationEmitGenericTypeParamerSerialization2.ts ===
type ExpandRecursively<T> = {} & {
>ExpandRecursively : { [P in keyof T]: T[P]; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^

[P in keyof T]: T[P]
}

type G<T = string> = {
>G : G<T>
> : ^^^^

get readonlyProperty(): T;
>readonlyProperty : T
> : ^

field: T;
>field : T
> : ^

method(p: T): T;
>method : (p: T) => T
> : ^ ^^ ^^^^^
>p : T
> : ^

fnField: (p: T) => T;
>fnField : (p: T) => T
> : ^ ^^ ^^^^^
>p : T
> : ^

set writeOnlyProperty(p: T);
>writeOnlyProperty : T
> : ^
>p : T
> : ^

get property(): T;
>property : T
> : ^

set property(p: T);
>property : T
> : ^
>p : T
> : ^

get divergentProperty(): string | T;
>divergentProperty : string | T
> : ^^^^^^^^^^

set divergentProperty(p: number | T);
>divergentProperty : string | T
> : ^^^^^^^^^^
>p : number | T
> : ^^^^^^^^^^

};

export const x = (() => null! as ExpandRecursively<G>)();
>x : { readonly readonlyProperty: string; field: string; method: (p: string) => string; fnField: (p: string) => string; writeOnlyProperty: string; property: string; divergentProperty: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>(() => null! as ExpandRecursively<G>)() : { readonly readonlyProperty: string; field: string; method: (p: string) => string; fnField: (p: string) => string; writeOnlyProperty: string; property: string; divergentProperty: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>(() => null! as ExpandRecursively<G>) : () => ExpandRecursively<G>
> : ^^^^^^
>() => null! as ExpandRecursively<G> : () => ExpandRecursively<G>
> : ^^^^^^
>null! as ExpandRecursively<G> : { readonly readonlyProperty: string; field: string; method: (p: string) => string; fnField: (p: string) => string; writeOnlyProperty: string; property: string; divergentProperty: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>null! : null
> : ^^^^


function makeV() {
>makeV : () => { readonly readonlyProperty: number; field: number; method(p: number): number; fnField: (p: number) => number; writeOnlyProperty: number; property: number; get divergentProperty(): string | number; set divergentProperty(p: number); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^

type X<T> = {
>X : { readonly readonlyProperty: T; field: T; method(p: T): T; fnField: (p: T) => T; writeOnlyProperty: T; property: T; get divergentProperty(): string | T; set divergentProperty(p: number | T); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^ ^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^

get readonlyProperty(): T;
>readonlyProperty : T
> : ^

field: T;
>field : T
> : ^

method(p: T): T;
>method : (p: T) => T
> : ^ ^^ ^^^^^
>p : T
> : ^

fnField: (p: T) => T;
>fnField : (p: T) => T
> : ^ ^^ ^^^^^
>p : T
> : ^

set writeOnlyProperty(p: T);
>writeOnlyProperty : T
> : ^
>p : T
> : ^

get property(): T;
>property : T
> : ^

set property(p: T);
>property : T
> : ^
>p : T
> : ^

get divergentProperty(): string | T;
>divergentProperty : string | T
> : ^^^^^^^^^^

set divergentProperty(p: number | T);
>divergentProperty : string | T
> : ^^^^^^^^^^
>p : number | T
> : ^^^^^^^^^^
}
return null! as X<number>
>null! as X<number> : { readonly readonlyProperty: number; field: number; method(p: number): number; fnField: (p: number) => number; writeOnlyProperty: number; property: number; get divergentProperty(): string | number; set divergentProperty(p: number); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
>null! : null
> : ^^^^
}

export const v = makeV();
>v : { readonly readonlyProperty: number; field: number; method(p: number): number; fnField: (p: number) => number; writeOnlyProperty: number; property: number; get divergentProperty(): string | number; set divergentProperty(p: number); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
>makeV() : { readonly readonlyProperty: number; field: number; method(p: number): number; fnField: (p: number) => number; writeOnlyProperty: number; property: number; get divergentProperty(): string | number; set divergentProperty(p: number); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
>makeV : () => { readonly readonlyProperty: number; field: number; method(p: number): number; fnField: (p: number) => number; writeOnlyProperty: number; property: number; get divergentProperty(): string | number; set divergentProperty(p: number); }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^

Original file line number Diff line number Diff line change
@@ -42,8 +42,8 @@ if (weirdoBox.done) {
weirdoBox.value;
>weirdoBox.value : number
> : ^^^^^^
>weirdoBox : { get done(): true; set done(v: T | null); value: number; }
> : ^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^
>weirdoBox : { get done(): true; set done(v: number | null); value: number; }
> : ^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : number
> : ^^^^^^
}
@@ -101,8 +101,8 @@ if (weirdoBox2.done) {
weirdoBox2.value;
>weirdoBox2.value : string | number
> : ^^^^^^^^^^^^^^^
>weirdoBox2 : { get done(): true; set done(v: T | null); value: string; } | { get done(): true; set done(v: T | null | undefined); value: number; }
> : ^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^^ ^^^
>weirdoBox2 : { get done(): true; set done(v: string | null); value: string; } | { get done(): true; set done(v: string | null | undefined); value: number; }
> : ^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
>value : string | number
> : ^^^^^^^^^^^^^^^
}
24 changes: 12 additions & 12 deletions tests/baselines/reference/mappedTypeRecursiveInference.types

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -3,10 +3,10 @@
=== objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts ===
// errors
var y = {
>y : { stringLiteral: any; 42: any; readonly e: any; f: any; this: any; super: any; var: any; class: any; typeof: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ "stringLiteral", 42, get e, set f, this, super, var, class, typeof} : { stringLiteral: any; 42: any; readonly e: any; f: any; this: any; super: any; var: any; class: any; typeof: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>y : { stringLiteral: any; 42: any; readonly e: void; f: any; this: any; super: any; var: any; class: any; typeof: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ "stringLiteral", 42, get e, set f, this, super, var, class, typeof} : { stringLiteral: any; 42: any; readonly e: void; f: any; this: any; super: any; var: any; class: any; typeof: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

"stringLiteral",
>"stringLiteral" : any
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @declaration: true

function wrapper<T>(value: T) {
return {
m() { return value; },
get g() { return value; },
}
}

export const w = wrapper(0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// @declaration: true

type ExpandRecursively<T> = {} & {
[P in keyof T]: T[P]
}

type G<T = string> = {
get readonlyProperty(): T;
field: T;
method(p: T): T;
fnField: (p: T) => T;
set writeOnlyProperty(p: T);
get property(): T;
set property(p: T);
get divergentProperty(): string | T;
set divergentProperty(p: number | T);
};

export const x = (() => null! as ExpandRecursively<G>)();


function makeV() {
type X<T> = {
get readonlyProperty(): T;
field: T;
method(p: T): T;
fnField: (p: T) => T;
set writeOnlyProperty(p: T);
get property(): T;
set property(p: T);
get divergentProperty(): string | T;
set divergentProperty(p: number | T);
}
return null! as X<number>
}

export const v = makeV();