Transfer all declared symbols onto the type from the interface that extends another (#55252)

This commit is contained in:
Mateusz Burzyński 2023-08-29 00:17:44 +02:00 committed by GitHub
parent 9a6a4ab1d5
commit 32ebbe05dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 165 additions and 1 deletions

View File

@ -12871,7 +12871,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const baseTypes = getBaseTypes(source);
if (baseTypes.length) {
if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
members = createSymbolTable(source.declaredProperties);
const symbolTable = createSymbolTable();
// copy all symbols (except type parameters), including the ones with internal names like `InternalSymbolName.Index`
for (const symbol of members.values()) {
if (!(symbol.flags & SymbolFlags.TypeParameter)) {
symbolTable.set(symbol.escapedName, symbol);
}
}
members = symbolTable;
}
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos);
const thisArgument = lastOrUndefined(typeArguments);

View File

@ -0,0 +1,75 @@
//// [tests/cases/compiler/classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts] ////
=== classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts ===
interface IObserver {
>IObserver : Symbol(IObserver, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 0))
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
>handleChange : Symbol(IObserver.handleChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 21))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 14))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
>observable : Symbol(observable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 26))
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 14))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
>change : Symbol(change, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 62))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 1, 16))
}
interface IObservable<T, TChange = unknown> {
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 22))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
get(): T;
>get : Symbol(IObservable.get, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 45))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 22))
readonly TChange: TChange;
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 4, 24), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 5, 10))
}
export interface IReader {
>IReader : Symbol(IReader, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 7, 1))
readObservable<T>(observable: IObservable<T, any>): T;
>readObservable : Symbol(IReader.readObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 9, 26))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
>observable : Symbol(observable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 19))
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 10, 16))
}
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
>ConvenientObservable : Symbol(ConvenientObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 11, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
>IObservable : Symbol(IObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 2, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
get TChange(): TChange { return null!; }
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 45), Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 91))
public abstract get(): T;
>get : Symbol(ConvenientObservable.get, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 14, 41))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 13, 43))
}
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
>BaseObservable : Symbol(BaseObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 16, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 37))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 39))
>ConvenientObservable : Symbol(ConvenientObservable, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 11, 1))
>T : Symbol(T, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 37))
>TChange : Symbol(TChange, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 39))
protected readonly observers = new Set<IObserver>();
>observers : Symbol(BaseObservable.observers, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 18, 98))
>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, --, --))
>IObserver : Symbol(IObserver, Decl(classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts, 0, 0))
}

View File

@ -0,0 +1,45 @@
//// [tests/cases/compiler/classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts] ////
=== classExtendingAbstractClassWithMemberCalledTheSameAsItsOwnTypeParam.ts ===
interface IObserver {
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
>handleChange : <T, TChange>(observable: IObservable<T, TChange>, change: TChange) => void
>observable : IObservable<T, TChange>
>change : TChange
}
interface IObservable<T, TChange = unknown> {
get(): T;
>get : () => T
readonly TChange: TChange;
>TChange : TChange
}
export interface IReader {
readObservable<T>(observable: IObservable<T, any>): T;
>readObservable : <T>(observable: IObservable<T, any>) => T
>observable : IObservable<T, any>
}
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
>ConvenientObservable : ConvenientObservable<T, TChange>
get TChange(): TChange { return null!; }
>TChange : TChange
>null! : never
public abstract get(): T;
>get : () => T
}
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
>BaseObservable : BaseObservable<T, TChange>
>ConvenientObservable : ConvenientObservable<T, TChange>
protected readonly observers = new Set<IObserver>();
>observers : Set<IObserver>
>new Set<IObserver>() : Set<IObserver>
>Set : SetConstructor
}

View File

@ -0,0 +1,25 @@
// @strict: true
// @lib: esnext
// @noEmit: true
interface IObserver {
handleChange<T, TChange>(observable: IObservable<T, TChange>, change: TChange): void;
}
interface IObservable<T, TChange = unknown> {
get(): T;
readonly TChange: TChange;
}
export interface IReader {
readObservable<T>(observable: IObservable<T, any>): T;
}
export abstract class ConvenientObservable<T, TChange> implements IObservable<T, TChange> {
get TChange(): TChange { return null!; }
public abstract get(): T;
}
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {
protected readonly observers = new Set<IObserver>();
}

View File

@ -0,0 +1,12 @@
/// <reference path="fourslash.ts" />
// https://github.com/microsoft/TypeScript/issues/55251
//// interface P {}
//// interface B extends P {
//// [k: string]: number;
//// }
//// declare const b: B;
//// b.t/*1*/est = 10;
verify.quickInfoAt("1", "(index) B[string]: number");