@@ -4916,8 +4916,8 @@ namespace ts {
4916
4916
}
4917
4917
4918
4918
function symbolTableToDeclarationStatements(symbolTable: SymbolTable, context: NodeBuilderContext, bundled?: boolean): Statement[] {
4919
- const serializePropertySymbolForClass = makeSerializePropertySymbol<ClassElement>(createProperty, SyntaxKind.MethodDeclaration);
4920
- const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol<TypeElement>((_decorators, mods, name, question, type, initializer) => createPropertySignature(mods, name, question, type, initializer), SyntaxKind.MethodSignature);
4919
+ const serializePropertySymbolForClass = makeSerializePropertySymbol<ClassElement>(createProperty, SyntaxKind.MethodDeclaration, /*useAcessors*/ true );
4920
+ const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol<TypeElement>((_decorators, mods, name, question, type, initializer) => createPropertySignature(mods, name, question, type, initializer), SyntaxKind.MethodSignature, /*useAcessors*/ false );
4921
4921
4922
4922
// TODO: Use `setOriginalNode` on original declaration names where possible so these declarations see some kind of
4923
4923
// declaration mapping
@@ -5734,7 +5734,23 @@ namespace ts {
5734
5734
questionOrExclamationToken: QuestionToken | undefined,
5735
5735
type: TypeNode | undefined,
5736
5736
initializer: Expression | undefined
5737
- ) => T, methodKind: SyntaxKind): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]) {
5737
+ ) => T, methodKind: SyntaxKind, useAccessors: true): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]);
5738
+ function makeSerializePropertySymbol<T extends Node>(createProperty: (
5739
+ decorators: readonly Decorator[] | undefined,
5740
+ modifiers: readonly Modifier[] | undefined,
5741
+ name: string | PropertyName,
5742
+ questionOrExclamationToken: QuestionToken | undefined,
5743
+ type: TypeNode | undefined,
5744
+ initializer: Expression | undefined
5745
+ ) => T, methodKind: SyntaxKind, useAccessors: false): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]);
5746
+ function makeSerializePropertySymbol<T extends Node>(createProperty: (
5747
+ decorators: readonly Decorator[] | undefined,
5748
+ modifiers: readonly Modifier[] | undefined,
5749
+ name: string | PropertyName,
5750
+ questionOrExclamationToken: QuestionToken | undefined,
5751
+ type: TypeNode | undefined,
5752
+ initializer: Expression | undefined
5753
+ ) => T, methodKind: SyntaxKind, useAccessors: boolean): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]) {
5738
5754
return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined) {
5739
5755
if (isStatic && (p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias))) {
5740
5756
// Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols
@@ -5750,7 +5766,40 @@ namespace ts {
5750
5766
const staticFlag = isStatic ? ModifierFlags.Static : 0;
5751
5767
const rawName = unescapeLeadingUnderscores(p.escapedName);
5752
5768
const name = getPropertyNameNodeForSymbolFromNameType(p, context) || createIdentifier(rawName);
5753
- if (p.flags & (SymbolFlags.Property | SymbolFlags.Accessor | SymbolFlags.Variable)) {
5769
+ const firstPropertyLikeDecl = find(p.declarations, or(isPropertyDeclaration, isAccessor, isVariableDeclaration, isPropertySignature, isBinaryExpression, isPropertyAccessExpression));
5770
+ if (p.flags & SymbolFlags.Accessor && useAccessors) {
5771
+ const result: AccessorDeclaration[] = [];
5772
+ if (p.flags & SymbolFlags.SetAccessor) {
5773
+ result.push(setTextRange(createSetAccessor(
5774
+ /*decorators*/ undefined,
5775
+ createModifiersFromModifierFlags(staticFlag),
5776
+ name,
5777
+ [createParameter(
5778
+ /*decorators*/ undefined,
5779
+ /*modifiers*/ undefined,
5780
+ /*dotDotDotToken*/ undefined,
5781
+ "arg",
5782
+ /*questionToken*/ undefined,
5783
+ serializeTypeForDeclaration(getTypeOfSymbol(p), p)
5784
+ )],
5785
+ /*body*/ undefined
5786
+ ), find(p.declarations, isSetAccessor) || firstPropertyLikeDecl));
5787
+ }
5788
+ if (p.flags & SymbolFlags.GetAccessor) {
5789
+ result.push(setTextRange(createGetAccessor(
5790
+ /*decorators*/ undefined,
5791
+ createModifiersFromModifierFlags(staticFlag),
5792
+ name,
5793
+ [],
5794
+ serializeTypeForDeclaration(getTypeOfSymbol(p), p),
5795
+ /*body*/ undefined
5796
+ ), find(p.declarations, isGetAccessor) || firstPropertyLikeDecl));
5797
+ }
5798
+ return result;
5799
+ }
5800
+ // This is an else/if as accessors and properties can't merge in TS, but might in JS
5801
+ // If this happens, we assume the accessor takes priority, as it imposes more constraints
5802
+ else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable)) {
5754
5803
return setTextRange(createProperty(
5755
5804
/*decorators*/ undefined,
5756
5805
createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | staticFlag),
@@ -5760,7 +5809,7 @@ namespace ts {
5760
5809
// TODO: https://github.com/microsoft/TypeScript/pull/32372#discussion_r328386357
5761
5810
// interface members can't have initializers, however class members _can_
5762
5811
/*initializer*/ undefined
5763
- ), filter (p.declarations, d => isPropertyDeclaration(d) || isAccessor(d) || isVariableDeclaration(d) || isPropertySignature(d ) || isBinaryExpression(d) || isPropertyAccessExpression(d))[0] );
5812
+ ), find (p.declarations, or(isPropertyDeclaration, isVariableDeclaration) ) || firstPropertyLikeDecl );
5764
5813
}
5765
5814
if (p.flags & (SymbolFlags.Method | SymbolFlags.Function)) {
5766
5815
const type = getTypeOfSymbol(p);
@@ -7340,7 +7389,7 @@ namespace ts {
7340
7389
}
7341
7390
}
7342
7391
else {
7343
- Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
7392
+ Debug.assert(!!getter, "there must exist a getter as we are current checking either setter or getter in this function");
7344
7393
errorOrSuggestion(noImplicitAny, getter!, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
7345
7394
}
7346
7395
return anyType;
0 commit comments