Skip to content

Commit 32ebbe0

Browse files
authored
Transfer all declared symbols onto the type from the interface that extends another (#55252)
1 parent 9a6a4ab commit 32ebbe0

5 files changed

+165
-1
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12871,7 +12871,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1287112871
const baseTypes = getBaseTypes(source);
1287212872
if (baseTypes.length) {
1287312873
if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
12874-
members = createSymbolTable(source.declaredProperties);
12874+
const symbolTable = createSymbolTable();
12875+
// copy all symbols (except type parameters), including the ones with internal names like `InternalSymbolName.Index`
12876+
for (const symbol of members.values()) {
12877+
if (!(symbol.flags & SymbolFlags.TypeParameter)) {
12878+
symbolTable.set(symbol.escapedName, symbol);
12879+
}
12880+
}
12881+
members = symbolTable;
1287512882
}
1287612883
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos);
1287712884
const thisArgument = lastOrUndefined(typeArguments);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//// [tests/cases/compiler/classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts] ////
2+
3+
=== classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts ===
4+
interface IObserver {
5+
>IObserver : Symbol(IObserver, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 0))
6+
7+
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
8+
>handleChange : Symbol(IObserver.handleChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 21))
9+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 14))
10+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
11+
>observable : Symbol(observable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 26))
12+
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
13+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 14))
14+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
15+
>change : Symbol(change, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 62))
16+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
17+
}
18+
19+
interface IObservable<T, TChange = unknown> {
20+
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
21+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 22))
22+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
23+
24+
get(): T;
25+
>get : Symbol(IObservable.get, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 45))
26+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 22))
27+
28+
readonly TChange: TChange;
29+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
30+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
31+
}
32+
33+
export interface IReader {
34+
>IReader : Symbol(IReader, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 7, 1))
35+
36+
readObservable<T>(observable: IObservable<T, any>): T;
37+
>readObservable : Symbol(IReader.readObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 9, 26))
38+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
39+
>observable : Symbol(observable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 19))
40+
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
41+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
42+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
43+
}
44+
45+
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
46+
>ConvenientObservable : Symbol(ConvenientObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 11, 1))
47+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
48+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
49+
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
50+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
51+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
52+
53+
get TChange(): TChange { return null!; }
54+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
55+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
56+
57+
public abstract get(): T;
58+
>get : Symbol(ConvenientObservable.get, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 14, 41))
59+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
60+
}
61+
62+
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
63+
>BaseObservable : Symbol(BaseObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 16, 1))
64+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 37))
65+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 39))
66+
>ConvenientObservable : Symbol(ConvenientObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 11, 1))
67+
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 37))
68+
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 39))
69+
70+
protected readonly observers = new Set<IObserver>();
71+
>observers : Symbol(BaseObservable.observers, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 98))
72+
>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
73+
>IObserver : Symbol(IObserver, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 0))
74+
}
75+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [tests/cases/compiler/classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts] ////
2+
3+
=== classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts ===
4+
interface IObserver {
5+
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
6+
>handleChange : <T, TChange>(observable: IObservable<T, TChange>, change: TChange) => void
7+
>observable : IObservable<T, TChange>
8+
>change : TChange
9+
}
10+
11+
interface IObservable<T, TChange = unknown> {
12+
get(): T;
13+
>get : () => T
14+
15+
readonly TChange: TChange;
16+
>TChange : TChange
17+
}
18+
19+
export interface IReader {
20+
readObservable<T>(observable: IObservable<T, any>): T;
21+
>readObservable : <T>(observable: IObservable<T, any>) => T
22+
>observable : IObservable<T, any>
23+
}
24+
25+
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
26+
>ConvenientObservable : ConvenientObservable<T, TChange>
27+
28+
get TChange(): TChange { return null!; }
29+
>TChange : TChange
30+
>null! : never
31+
32+
public abstract get(): T;
33+
>get : () => T
34+
}
35+
36+
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
37+
>BaseObservable : BaseObservable<T, TChange>
38+
>ConvenientObservable : ConvenientObservable<T, TChange>
39+
40+
protected readonly observers = new Set<IObserver>();
41+
>observers : Set<IObserver>
42+
>new Set<IObserver>() : Set<IObserver>
43+
>Set : SetConstructor
44+
}
45+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @strict: true
2+
// @lib: esnext
3+
// @noEmit: true
4+
5+
interface IObserver {
6+
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
7+
}
8+
9+
interface IObservable<T, TChange = unknown> {
10+
get(): T;
11+
readonly TChange: TChange;
12+
}
13+
14+
export interface IReader {
15+
readObservable<T>(observable: IObservable<T, any>): T;
16+
}
17+
18+
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
19+
get TChange(): TChange { return null!; }
20+
public abstract get(): T;
21+
}
22+
23+
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
24+
protected readonly observers = new Set<IObserver>();
25+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// https://github.com/microsoft/TypeScript/issues/55251
4+
5+
//// interface P {}
6+
//// interface B extends P {
7+
//// [k: string]: number;
8+
//// }
9+
//// declare const b: B;
10+
//// b.t/*1*/est = 10;
11+
12+
verify.quickInfoAt("1", "(index) B[string]: number");

0 commit comments

Comments
 (0)