diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 4875b43d4e867..d3f752b931ac0 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -47336,7 +47336,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const errorMessage = overriddenInstanceProperty ?
Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property :
Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor;
- error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType), typeToString(type));
+ error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(getDeclaredTypeOfSymbol(base.parent!)), typeToString(type));
}
else if (useDefineForClassFields) {
const uninitialized = derived.declarations?.find(d => d.kind === SyntaxKind.PropertyDeclaration && !(d as PropertyDeclaration).initializer);
diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts
index 471cbab82c6c9..17ff1280f40c0 100644
--- a/src/services/codefixes/fixAddMissingMember.ts
+++ b/src/services/codefixes/fixAddMissingMember.ts
@@ -7,7 +7,6 @@ import {
createSignatureDeclarationFromSignature,
createStubbedBody,
eachDiagnostic,
- getAllSupers,
ImportAdder,
registerCodeFix,
} from "../_namespaces/ts.codefix.js";
@@ -40,6 +39,7 @@ import {
firstOrUndefinedIterator,
FunctionExpression,
getCheckFlags,
+ getClassExtendsHeritageElement,
getClassLikeDeclarationOfSymbol,
getEmitScriptTarget,
getEscapedTextOfJsxAttributeName,
@@ -797,3 +797,18 @@ function findScope(node: Node) {
}
return getSourceFileOfNode(node);
}
+
+function getAllSupers(decl: ClassLikeDeclaration | InterfaceDeclaration | undefined, checker: TypeChecker): readonly ClassLikeDeclaration[] {
+ const res: ClassLikeDeclaration[] = [];
+ while (decl) {
+ const superElement = getClassExtendsHeritageElement(decl);
+ const superSymbol = superElement && checker.getSymbolAtLocation(superElement.expression);
+ if (!superSymbol) break;
+ const symbol = superSymbol.flags & SymbolFlags.Alias ? checker.getAliasedSymbol(superSymbol) : superSymbol;
+ const superDecl = symbol.declarations && find(symbol.declarations, isClassLike);
+ if (!superDecl) break;
+ res.push(superDecl);
+ decl = superDecl;
+ }
+ return res;
+}
diff --git a/src/services/codefixes/fixPropertyOverrideAccessor.ts b/src/services/codefixes/fixPropertyOverrideAccessor.ts
index c1b446bcf7d34..2c831d9efb400 100644
--- a/src/services/codefixes/fixPropertyOverrideAccessor.ts
+++ b/src/services/codefixes/fixPropertyOverrideAccessor.ts
@@ -2,7 +2,6 @@ import {
codeFixAll,
createCodeFixAction,
generateAccessorFromProperty,
- getAllSupers,
registerCodeFix,
} from "../_namespaces/ts.codefix.js";
import {
@@ -10,12 +9,15 @@ import {
CodeFixContext,
Debug,
Diagnostics,
+ getEffectiveBaseTypeNode,
getSourceFileOfNode,
getTextOfPropertyName,
getTokenAtPosition,
isAccessor,
+ isClassExpression,
isClassLike,
- singleOrUndefined,
+ isComputedPropertyName,
+ skipParentheses,
SourceFile,
unescapeLeadingUnderscores,
} from "../_namespaces/ts.js";
@@ -56,15 +58,20 @@ function doChange(file: SourceFile, start: number, length: number, code: number,
else if (code === Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor.code) {
const checker = context.program.getTypeChecker();
const node = getTokenAtPosition(file, start).parent;
+ if (isComputedPropertyName(node)) {
+ return;
+ }
Debug.assert(isAccessor(node), "error span of fixPropertyOverrideAccessor should only be on an accessor");
const containingClass = node.parent;
Debug.assert(isClassLike(containingClass), "erroneous accessors should only be inside classes");
- const base = singleOrUndefined(getAllSupers(containingClass, checker));
- if (!base) return [];
-
- const name = unescapeLeadingUnderscores(getTextOfPropertyName(node.name));
- const baseProp = checker.getPropertyOfType(checker.getTypeAtLocation(base), name);
- if (!baseProp || !baseProp.valueDeclaration) return [];
+ const baseTypeNode = getEffectiveBaseTypeNode(containingClass);
+ if (!baseTypeNode) return;
+ const expression = skipParentheses(baseTypeNode.expression);
+ const base = isClassExpression(expression) ? expression.symbol : checker.getSymbolAtLocation(expression);
+ if (!base) return;
+ const baseType = checker.getDeclaredTypeOfSymbol(base);
+ const baseProp = checker.getPropertyOfType(baseType, unescapeLeadingUnderscores(getTextOfPropertyName(node.name)));
+ if (!baseProp || !baseProp.valueDeclaration) return;
startPosition = baseProp.valueDeclaration.pos;
endPosition = baseProp.valueDeclaration.end;
diff --git a/src/services/codefixes/generateAccessors.ts b/src/services/codefixes/generateAccessors.ts
index 75837f080749f..76ffd62b2c9a4 100644
--- a/src/services/codefixes/generateAccessors.ts
+++ b/src/services/codefixes/generateAccessors.ts
@@ -9,9 +9,7 @@ import {
Diagnostics,
factory,
FileTextChanges,
- find,
findAncestor,
- getClassExtendsHeritageElement,
getDecorators,
getEffectiveModifierFlags,
getFirstConstructorWithBody,
@@ -22,7 +20,6 @@ import {
hasEffectiveReadonlyModifier,
hasStaticModifier,
Identifier,
- InterfaceDeclaration,
isClassLike,
isElementAccessExpression,
isFunctionLike,
@@ -50,10 +47,8 @@ import {
startsWithUnderscore,
StringLiteral,
suppressLeadingAndTrailingTrivia,
- SymbolFlags,
SyntaxKind,
textChanges,
- TypeChecker,
TypeNode,
} from "../_namespaces/ts.js";
@@ -321,22 +316,3 @@ function getDeclarationType(declaration: AcceptedDeclaration, program: Program):
}
return typeNode;
}
-
-/** @internal */
-export function getAllSupers(decl: ClassOrInterface | undefined, checker: TypeChecker): readonly ClassOrInterface[] {
- const res: ClassLikeDeclaration[] = [];
- while (decl) {
- const superElement = getClassExtendsHeritageElement(decl);
- const superSymbol = superElement && checker.getSymbolAtLocation(superElement.expression);
- if (!superSymbol) break;
- const symbol = superSymbol.flags & SymbolFlags.Alias ? checker.getAliasedSymbol(superSymbol) : superSymbol;
- const superDecl = symbol.declarations && find(symbol.declarations, isClassLike);
- if (!superDecl) break;
- res.push(superDecl);
- decl = superDecl;
- }
- return res;
-}
-
-/** @internal */
-export type ClassOrInterface = ClassLikeDeclaration | InterfaceDeclaration;
diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 48fdb95aa0cff..b8b131ca3b56f 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -51,6 +51,7 @@ import {
isClassExpression,
isClassLike,
isClassStaticBlockDeclaration,
+ isComputedPropertyName,
isConstructorDeclaration,
isDeclarationFileName,
isDefaultClause,
@@ -64,6 +65,7 @@ import {
isJSDocOverrideTag,
isJsxOpeningLikeElement,
isJumpStatementTarget,
+ isKnownSymbol,
isModifier,
isModuleSpecifierLike,
isNamedDeclaration,
@@ -328,14 +330,29 @@ function getDefinitionFromOverriddenMember(typeChecker: TypeChecker, node: Node)
const expression = skipParentheses(baseTypeNode.expression);
const base = isClassExpression(expression) ? expression.symbol : typeChecker.getSymbolAtLocation(expression);
if (!base) return;
+ const baseType = hasStaticModifier(classElement) ? typeChecker.getTypeOfSymbol(base) : typeChecker.getDeclaredTypeOfSymbol(base);
+ let baseProp: Symbol | undefined;
- const name = unescapeLeadingUnderscores(getTextOfPropertyName(classElement.name));
- const symbol = hasStaticModifier(classElement)
- ? typeChecker.getPropertyOfType(typeChecker.getTypeOfSymbol(base), name)
- : typeChecker.getPropertyOfType(typeChecker.getDeclaredTypeOfSymbol(base), name);
- if (!symbol) return;
+ if (isComputedPropertyName(classElement.name)) {
+ const prop = typeChecker.getSymbolAtLocation(classElement.name);
- return getDefinitionFromSymbol(typeChecker, symbol, node);
+ if (!prop) {
+ return;
+ }
+
+ if (isKnownSymbol(prop)) {
+ baseProp = find(typeChecker.getPropertiesOfType(baseType), s => s.escapedName === prop.escapedName);
+ }
+ else {
+ baseProp = typeChecker.getPropertyOfType(baseType, unescapeLeadingUnderscores(prop.escapedName));
+ }
+ }
+ else {
+ baseProp = typeChecker.getPropertyOfType(baseType, unescapeLeadingUnderscores(getTextOfPropertyName(classElement.name)));
+ }
+ if (!baseProp) return;
+
+ return getDefinitionFromSymbol(typeChecker, baseProp, node);
}
/** @internal */
diff --git a/tests/baselines/reference/accessorsOverrideProperty10.errors.txt b/tests/baselines/reference/accessorsOverrideProperty10.errors.txt
new file mode 100644
index 0000000000000..9ba82aa7b4f5f
--- /dev/null
+++ b/tests/baselines/reference/accessorsOverrideProperty10.errors.txt
@@ -0,0 +1,16 @@
+accessorsOverrideProperty10.ts(6,7): error TS2611: 'x' is defined as a property in class 'A', but is overridden here in 'C' as an accessor.
+
+
+==== accessorsOverrideProperty10.ts (1 errors) ====
+ class A {
+ x = 1;
+ }
+ class B extends A {}
+ class C extends B {
+ get x() {
+ ~
+!!! error TS2611: 'x' is defined as a property in class 'A', but is overridden here in 'C' as an accessor.
+ return 2;
+ }
+ }
+
\ No newline at end of file
diff --git a/tests/baselines/reference/accessorsOverrideProperty10.symbols b/tests/baselines/reference/accessorsOverrideProperty10.symbols
new file mode 100644
index 0000000000000..f0b2c93f29d02
--- /dev/null
+++ b/tests/baselines/reference/accessorsOverrideProperty10.symbols
@@ -0,0 +1,24 @@
+//// [tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty10.ts] ////
+
+=== accessorsOverrideProperty10.ts ===
+class A {
+>A : Symbol(A, Decl(accessorsOverrideProperty10.ts, 0, 0))
+
+ x = 1;
+>x : Symbol(A.x, Decl(accessorsOverrideProperty10.ts, 0, 9))
+}
+class B extends A {}
+>B : Symbol(B, Decl(accessorsOverrideProperty10.ts, 2, 1))
+>A : Symbol(A, Decl(accessorsOverrideProperty10.ts, 0, 0))
+
+class C extends B {
+>C : Symbol(C, Decl(accessorsOverrideProperty10.ts, 3, 20))
+>B : Symbol(B, Decl(accessorsOverrideProperty10.ts, 2, 1))
+
+ get x() {
+>x : Symbol(C.x, Decl(accessorsOverrideProperty10.ts, 4, 19))
+
+ return 2;
+ }
+}
+
diff --git a/tests/baselines/reference/accessorsOverrideProperty10.types b/tests/baselines/reference/accessorsOverrideProperty10.types
new file mode 100644
index 0000000000000..8615b3d534492
--- /dev/null
+++ b/tests/baselines/reference/accessorsOverrideProperty10.types
@@ -0,0 +1,35 @@
+//// [tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty10.ts] ////
+
+=== accessorsOverrideProperty10.ts ===
+class A {
+>A : A
+> : ^
+
+ x = 1;
+>x : number
+> : ^^^^^^
+>1 : 1
+> : ^
+}
+class B extends A {}
+>B : B
+> : ^
+>A : A
+> : ^
+
+class C extends B {
+>C : C
+> : ^
+>B : B
+> : ^
+
+ get x() {
+>x : number
+> : ^^^^^^
+
+ return 2;
+>2 : 2
+> : ^
+ }
+}
+
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember17.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember17.baseline.jsonc
new file mode 100644
index 0000000000000..4695ad301d280
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember17.baseline.jsonc
@@ -0,0 +1,23 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember17.ts ===
+// const entityKind = Symbol.for("drizzle:entityKind");
+//
+// abstract class MySqlColumn {
+// <|static readonly [|[entityKind]|]: string = "MySqlColumn";|>
+// }
+//
+// export class MySqlVarBinary extends MySqlColumn {
+// static /*GOTO DEF*/override readonly [entityKind]: string = "MySqlVarBinary";
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[entityKind]",
+ "containerName": "MySqlColumn",
+ "isLocal": true,
+ "isAmbient": false,
+ "unverified": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember18.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember18.baseline.jsonc
new file mode 100644
index 0000000000000..c43d1d6aac3a8
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember18.baseline.jsonc
@@ -0,0 +1,23 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember18.ts ===
+// const entityKind = Symbol.for("drizzle:entityKind");
+//
+// abstract class MySqlColumn {
+// <|readonly [|[entityKind]|]: string = "MySqlColumn";|>
+// }
+//
+// export class MySqlVarBinary extends MySqlColumn {
+// /*GOTO DEF*/override readonly [entityKind]: string = "MySqlVarBinary";
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[entityKind]",
+ "containerName": "MySqlColumn",
+ "isLocal": true,
+ "isAmbient": false,
+ "unverified": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember19.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember19.baseline.jsonc
new file mode 100644
index 0000000000000..cdcacbeb56245
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember19.baseline.jsonc
@@ -0,0 +1,23 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember19.ts ===
+// const prop = "foo" as const;
+//
+// abstract class A {
+// <|static readonly [|[prop]|] = "A";|>
+// }
+//
+// export class B extends A {
+// static /*GOTO DEF*/override readonly [prop] = "B";
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[prop]",
+ "containerName": "A",
+ "isLocal": true,
+ "isAmbient": false,
+ "unverified": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember20.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember20.baseline.jsonc
new file mode 100644
index 0000000000000..7c16b895ffd07
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember20.baseline.jsonc
@@ -0,0 +1,23 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember20.ts ===
+// const prop = "foo" as const;
+//
+// abstract class A {
+// <|readonly [|[prop]|] = "A";|>
+// }
+//
+// export class B extends A {
+// /*GOTO DEF*/override readonly [prop] = "B";
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[prop]",
+ "containerName": "A",
+ "isLocal": true,
+ "isAmbient": false,
+ "unverified": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember21.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember21.baseline.jsonc
new file mode 100644
index 0000000000000..94eb0f3896e25
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember21.baseline.jsonc
@@ -0,0 +1,22 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember21.ts ===
+// const prop = "foo" as const;
+//
+// abstract class A {}
+//
+// export class B extends A {
+// <|static /*GOTO DEF*/override readonly [|[prop]|] = "B";|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember22.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember22.baseline.jsonc
new file mode 100644
index 0000000000000..a52d8e8b1945d
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember22.baseline.jsonc
@@ -0,0 +1,22 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember22.ts ===
+// const prop = "foo" as const;
+//
+// abstract class A {}
+//
+// export class B extends A {
+// /*GOTO DEF*/<|override readonly [|[prop]|] = "B";|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "property",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember23.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember23.baseline.jsonc
new file mode 100644
index 0000000000000..7007ff335575f
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember23.baseline.jsonc
@@ -0,0 +1,21 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember23.ts ===
+// --- (line: 4) skipped ---
+// }
+//
+// export class B extends A {
+// <|static /*GOTO DEF*/override [|[prop]|]() {}|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "method",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember24.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember24.baseline.jsonc
new file mode 100644
index 0000000000000..f6222b4352c2d
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember24.baseline.jsonc
@@ -0,0 +1,21 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember24.ts ===
+// --- (line: 4) skipped ---
+// }
+//
+// export class B extends A {
+// /*GOTO DEF*/<|override [|[prop]|]() {}|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "method",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember25.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember25.baseline.jsonc
new file mode 100644
index 0000000000000..63658d0c3ccdc
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember25.baseline.jsonc
@@ -0,0 +1,22 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember25.ts ===
+// const prop: symbol = Symbol();
+//
+// abstract class A {}
+//
+// export class B extends A {
+// <|static /*GOTO DEF*/override [|[prop]|]() {}|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "method",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember26.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember26.baseline.jsonc
new file mode 100644
index 0000000000000..2ced39b72e2fc
--- /dev/null
+++ b/tests/baselines/reference/goToDefinitionOverriddenMember26.baseline.jsonc
@@ -0,0 +1,22 @@
+// === goToDefinition ===
+// === /tests/cases/fourslash/goToDefinitionOverriddenMember26.ts ===
+// const prop: symbol = Symbol();
+//
+// abstract class A {}
+//
+// export class B extends A {
+// /*GOTO DEF*/<|override [|[prop]|]() {}|>
+// }
+
+ // === Details ===
+ [
+ {
+ "kind": "method",
+ "name": "[prop]",
+ "containerName": "B",
+ "isLocal": false,
+ "isAmbient": false,
+ "unverified": false,
+ "failedAliasResolution": false
+ }
+ ]
\ No newline at end of file
diff --git a/tests/baselines/reference/propertyOverridesAccessors6.errors.txt b/tests/baselines/reference/propertyOverridesAccessors6.errors.txt
new file mode 100644
index 0000000000000..cda1185c86522
--- /dev/null
+++ b/tests/baselines/reference/propertyOverridesAccessors6.errors.txt
@@ -0,0 +1,16 @@
+propertyOverridesAccessors6.ts(8,3): error TS2610: 'x' is defined as an accessor in class 'A', but is overridden here in 'C' as an instance property.
+
+
+==== propertyOverridesAccessors6.ts (1 errors) ====
+ class A {
+ get x() {
+ return 2;
+ }
+ }
+ class B extends A {}
+ class C extends B {
+ x = 1;
+ ~
+!!! error TS2610: 'x' is defined as an accessor in class 'A', but is overridden here in 'C' as an instance property.
+ }
+
\ No newline at end of file
diff --git a/tests/baselines/reference/propertyOverridesAccessors6.symbols b/tests/baselines/reference/propertyOverridesAccessors6.symbols
new file mode 100644
index 0000000000000..289b25db4e55e
--- /dev/null
+++ b/tests/baselines/reference/propertyOverridesAccessors6.symbols
@@ -0,0 +1,24 @@
+//// [tests/cases/conformance/classes/propertyMemberDeclarations/propertyOverridesAccessors6.ts] ////
+
+=== propertyOverridesAccessors6.ts ===
+class A {
+>A : Symbol(A, Decl(propertyOverridesAccessors6.ts, 0, 0))
+
+ get x() {
+>x : Symbol(A.x, Decl(propertyOverridesAccessors6.ts, 0, 9))
+
+ return 2;
+ }
+}
+class B extends A {}
+>B : Symbol(B, Decl(propertyOverridesAccessors6.ts, 4, 1))
+>A : Symbol(A, Decl(propertyOverridesAccessors6.ts, 0, 0))
+
+class C extends B {
+>C : Symbol(C, Decl(propertyOverridesAccessors6.ts, 5, 20))
+>B : Symbol(B, Decl(propertyOverridesAccessors6.ts, 4, 1))
+
+ x = 1;
+>x : Symbol(C.x, Decl(propertyOverridesAccessors6.ts, 6, 19))
+}
+
diff --git a/tests/baselines/reference/propertyOverridesAccessors6.types b/tests/baselines/reference/propertyOverridesAccessors6.types
new file mode 100644
index 0000000000000..dc9dfd74307e4
--- /dev/null
+++ b/tests/baselines/reference/propertyOverridesAccessors6.types
@@ -0,0 +1,35 @@
+//// [tests/cases/conformance/classes/propertyMemberDeclarations/propertyOverridesAccessors6.ts] ////
+
+=== propertyOverridesAccessors6.ts ===
+class A {
+>A : A
+> : ^
+
+ get x() {
+>x : number
+> : ^^^^^^
+
+ return 2;
+>2 : 2
+> : ^
+ }
+}
+class B extends A {}
+>B : B
+> : ^
+>A : A
+> : ^
+
+class C extends B {
+>C : C
+> : ^
+>B : B
+> : ^
+
+ x = 1;
+>x : number
+> : ^^^^^^
+>1 : 1
+> : ^
+}
+
diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty10.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty10.ts
new file mode 100644
index 0000000000000..43aff8ab7492e
--- /dev/null
+++ b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty10.ts
@@ -0,0 +1,14 @@
+// @strict: esnext
+// @target: esnext
+// @useDefineForClassFields: true
+// @noEmit: true
+
+class A {
+ x = 1;
+}
+class B extends A {}
+class C extends B {
+ get x() {
+ return 2;
+ }
+}
diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/propertyOverridesAccessors6.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/propertyOverridesAccessors6.ts
new file mode 100644
index 0000000000000..9343c50daa35d
--- /dev/null
+++ b/tests/cases/conformance/classes/propertyMemberDeclarations/propertyOverridesAccessors6.ts
@@ -0,0 +1,14 @@
+// @strict: esnext
+// @target: esnext
+// @useDefineForClassFields: true
+// @noEmit: true
+
+class A {
+ get x() {
+ return 2;
+ }
+}
+class B extends A {}
+class C extends B {
+ x = 1;
+}
diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess4.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess4.ts
new file mode 100644
index 0000000000000..fbebbed4deeec
--- /dev/null
+++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess4.ts
@@ -0,0 +1,16 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop = Symbol.for('foo');
+////
+//// class A {
+//// [prop] = 1;
+//// }
+//// class B extends A {
+//// get [prop]() { return 2; }
+//// }
+
+verify.not.codeFixAvailable("fixPropertyOverrideAccessor");
diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess5.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess5.ts
new file mode 100644
index 0000000000000..c0e87a965b636
--- /dev/null
+++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess5.ts
@@ -0,0 +1,29 @@
+///
+
+// @strict: true
+
+//// class A {
+//// x = 1;
+//// }
+//// class B extends A {}
+//// class C extends B {
+//// get x() { return 2; }
+//// }
+
+verify.codeFix({
+ description: `Generate 'get' and 'set' accessors`,
+ newFileContent: `class A {
+ private _x = 1;
+ public get x() {
+ return this._x;
+ }
+ public set x(value) {
+ this._x = value;
+ }
+}
+class B extends A {}
+class C extends B {
+ get x() { return 2; }
+}`,
+ index: 0
+})
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember17.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember17.ts
new file mode 100644
index 0000000000000..5b18c009aa8c5
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember17.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const entityKind = Symbol.for("drizzle:entityKind");
+////
+//// abstract class MySqlColumn {
+//// static readonly /*2*/[entityKind]: string = "MySqlColumn";
+//// }
+////
+//// export class MySqlVarBinary extends MySqlColumn {
+//// static [|/*1*/override|] readonly [entityKind]: string = "MySqlVarBinary";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember18.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember18.ts
new file mode 100644
index 0000000000000..66bd417bfe6e9
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember18.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const entityKind = Symbol.for("drizzle:entityKind");
+////
+//// abstract class MySqlColumn {
+//// readonly /*2*/[entityKind]: string = "MySqlColumn";
+//// }
+////
+//// export class MySqlVarBinary extends MySqlColumn {
+//// [|/*1*/override|] readonly [entityKind]: string = "MySqlVarBinary";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember19.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember19.ts
new file mode 100644
index 0000000000000..ab42e0c52c3df
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember19.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop = "foo" as const;
+////
+//// abstract class A {
+//// static readonly /*2*/[prop] = "A";
+//// }
+////
+//// export class B extends A {
+//// static [|/*1*/override|] readonly [prop] = "B";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember20.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember20.ts
new file mode 100644
index 0000000000000..4fdaf09865eb2
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember20.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop = "foo" as const;
+////
+//// abstract class A {
+//// readonly /*2*/[prop] = "A";
+//// }
+////
+//// export class B extends A {
+//// [|/*1*/override|] readonly [prop] = "B";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember21.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember21.ts
new file mode 100644
index 0000000000000..1da6ee87ee98c
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember21.ts
@@ -0,0 +1,15 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop = "foo" as const;
+////
+//// abstract class A {}
+////
+//// export class B extends A {
+//// static [|/*1*/override|] readonly [prop] = "B";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember22.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember22.ts
new file mode 100644
index 0000000000000..a628e91fc0f82
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember22.ts
@@ -0,0 +1,15 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop = "foo" as const;
+////
+//// abstract class A {}
+////
+//// export class B extends A {
+//// [|/*1*/override|] readonly [prop] = "B";
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember23.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember23.ts
new file mode 100644
index 0000000000000..5dfd57b0aabff
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember23.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop: symbol = Symbol();
+////
+//// abstract class A {
+//// static [prop]() {}
+//// }
+////
+//// export class B extends A {
+//// static [|/*1*/override|] [prop]() {}
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember24.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember24.ts
new file mode 100644
index 0000000000000..347c78c0478fa
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember24.ts
@@ -0,0 +1,17 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop: symbol = Symbol();
+////
+//// abstract class A {
+//// [prop]() {}
+//// }
+////
+//// export class B extends A {
+//// [|/*1*/override|] [prop]() {}
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember25.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember25.ts
new file mode 100644
index 0000000000000..e03dcb0c89098
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember25.ts
@@ -0,0 +1,15 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop: symbol = Symbol();
+////
+//// abstract class A {}
+////
+//// export class B extends A {
+//// static [|/*1*/override|] [prop]() {}
+//// }
+
+verify.baselineGoToDefinition("1");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember26.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember26.ts
new file mode 100644
index 0000000000000..2791cae54da99
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember26.ts
@@ -0,0 +1,15 @@
+///
+
+// @strict: true
+// @target: esnext
+// @lib: esnext
+
+//// const prop: symbol = Symbol();
+////
+//// abstract class A {}
+////
+//// export class B extends A {
+//// [|/*1*/override|] [prop]() {}
+//// }
+
+verify.baselineGoToDefinition("1");